gpt4 book ai didi

c++ - 如何避免这种类似单例的设计模式?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:42:14 26 4
gpt4 key购买 nike

我们有一个渲染管道,我们当前的代码为管道的每个阶段创建一个实例。这意味着随着我们更新代码,我们将不断更新管道(或多组管道)代码。这感觉像是我们应该进行额外抽象的地方,但我们不确定如何进行。

编辑:看来我的伪代码不太好理解。也许图表会更容易地解释该模式。

框图链接:http://yuml.me/0650d1bf.svg

// yuml.me
[GenericRenderStage|render|Parent Class]<---[Shadow1RenderStage|render|Derived Class]
[Shadow1RenderStage|render|Derived Class]<---[_shadowRenderStage1|Singleton Object]
[GenericRenderStage|render|Parent Class]<---[Shadow2RenderStage|render|Derived Class]
[Shadow2RenderStage|render|Derived Class]<---[_shadowRenderStage2|Singleton Object]
[GenericRenderStage|render|Parent Class]<---[ShadowNRenderStage|render|Derived Class]
[ShadowNRenderStage|render|Derived Class]<---[_shadowRenderStageN|Singleton Object]

父类伪c++代码:

class GenericRenderStage(...) {
/// Render method
virtual void render(void) {
/// handles drawing code
}

class Shadow1RenderStage : GenericRenderStage(...) {
/// Render method
void render(void) {
/// handles custom drawing for shadow1 stage
}

class Shadow2RenderStage : GenericRenderStage(...) {
/// Render method
void render(void) {
/// handles custom drawing for shadow2 stage
}

...

class ShadowNRenderStage : GenericRenderStage(...) {
/// Render method
void render(void) {
/// handles custom drawing for shadowN stage
}

然后我们的管道有一组相同类型的模式...

class GenericRenderPipeLine(...) {
/// Render method
virtual void render(void) {
/// handles drawing code
}

class ShadowRenderPipeline : GenericRenderPipeLine() {
/// instantiate stages for this pipeline
ShadowRenderPipeline() {
shadow1Stage = new Shadow1RenderStage();
shadow2Stage = new Shadow2RenderStage();
...
shadowNStage = new ShadowNRenderStage();
}

/// Render method
void render(void) {
/// setup fbo
/// for each render stage, render
shadow1Stage.render()
shadow2Stage.render()
...
shadowNStage.render()
/// handle fbo
}

这里的模式似乎确实有问题。我们有一个父类,它基本上是一组虚拟方法,由只有一个实例的自定义类继承。

最佳答案

据我了解(如果我错了,请纠正我),每个渲染阶段都是独一无二的,并不真正遵循任何特定的模式。所以,我认为最好保持原样;将每个渲染阶段都放在一个独立的文件/类中。

但是,我认为您可以通过消除渲染管道继承结构来减少大量工作。所有这些看起来都是相同的(即它们有一定数量的阶段并在每个阶段调用 render() )。如果您改用动态的通用管道会怎么样?

#include <vector>
#include <memory>

class DynamicRenderPipeline {

private:
std::vector<std::unique_ptr<GenericRenderStage>> renderStages;

public:

void add(std::unique_ptr<GenericRenderStage> renderStage) {
renderStages.push_back(std::move(renderStage));
}

void render() {
for (auto& stage : renderStages) {
stage->render();
}
}
};

int main() {
DynamicRenderPipeline pipeline;
pipeline.add(std::unique_ptr<GenericRenderStage>(new RenderStage1()));
pipeline.add(std::unique_ptr<GenericRenderStage>(new RenderStage2()));
pipeline.add(std::unique_ptr<GenericRenderStage>(new RenderStage3()));
pipeline.add(std::unique_ptr<GenericRenderStage>(new RenderStage4()));
pipeline.add(std::unique_ptr<GenericRenderStage>(new RenderStage5()));

pipeline.render();
}

您现在可以只创建 DynamicRenderPipeline 的实例并添加您想要的任何阶段。当您对其调用 render() 时,它将以正确的顺序遍历所有添加的渲染阶段。现在您的管道只依赖于 GenericRenderStage 接口(interface)。如果您不使用 C++11,您可以对原始指针执行相同的操作(而不是 unique_ptr),但您必须确保在管道的析构函数中清理您的 vector 。

关于c++ - 如何避免这种类似单例的设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26681883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com