装饰模式在这里是一个合适的选择吗?

时间:2015-05-22 15:18:22

标签: c++ design-patterns decorator

请考虑以下代码。通过A::doit()B对象应该总计增加3. Decorated1对象应该总计增加4, 并且Decorated2对象应该总计增加5. A对象是这些派生类型的组合仍应执行其特殊操作"但是要增加总数的个体增加的最大值(不是总和)。但是装饰器模式是获得总和而不是最大值。我是否必须放弃装饰模式?

#include <iostream>

int total = 0;

struct A {
public:
    virtual void doIt() = 0;
};

struct Decorator : public A {
    A* a;
    Decorator (A* a_) : a(a_) {}
    virtual void doIt() override {a->doIt();}
};

struct B : public A {
    virtual void doIt() override {
        total += 3;
        std::cout << "Special actions by B carried out.\n";
    }
};

struct Decorated1 : public Decorator {
    using Decorator::Decorator;
    virtual void doIt() override {
        Decorator::doIt();
        total += 4;
        std::cout << "Special actions by Decorated1 carried out.\n";
    }
};

struct Decorated2 : public Decorator {
    using Decorator::Decorator;
    virtual void doIt() override {
        Decorator::doIt();
        total += 5;
        std::cout << "Special actions by Decorated2 carried out.\n";
    }
};

int main() {
    A* decorated1_2 = new Decorated2(new Decorated1(new B));
    decorated1_2->doIt();
    std::cout << "total = " << total << std::endl;
}

输出:

Special actions by B carried out.  // Good I want this.
Special actions by Decorated1 carried out.  // Good I want this.
Special actions by Decorated2 carried out.  // Good I want this.
total = 12  // No, it is supposed to be 5, not the sum 3+4+5.

2 个答案:

答案 0 :(得分:3)

装饰器模式是一类结构模式,即结构模式可帮助您为当前功能添加和构建功能

这就是为什么你得到所有装饰器的总和为12(B特征&lt;&lt;&gt;&gt; + Decorative1特征&lt;&lt;&gt;&gt; + Decorative2特征&lt;&lt;&gt;&gt;&gt;)。 / p>

如果你想继续处理结构模式,如果你想得到预期的结果,你必须分别初始化并将A类的对象发送给所有的装饰器类。

否则,您可以使用策略设计模式并获得相同的结果..

另一个好的选择是使用Creational设计模式

你可以在这里用java代码检查这些关于设计模式的例子。 https://github.com/pavansn/java-design-patterns

希望有所帮助

答案 1 :(得分:2)

您需要将doIt的功能分开。您无法在函数中应用增量,而会执行一些特殊操作,并且不会同时执行这两项操作。

有两种方法可以实现这一目标。两者都要求您将增量隔离到自己的方法。

  • 使增量值成为多态属性并在基类中应用增量,并且不要调用超类。
  • 完全覆盖派生类
  • 中的增量