【问题标题】:Is the Decorator Pattern a suitable choice here?装饰器模式在这里是一个合适的选择吗?
【发布时间】:2015-05-22 15:18:21
【问题描述】:

考虑下面的代码。通过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.

【问题讨论】:

  • Decorator 不应该继承自A,否则就不是装饰器...
  • 另外,您如何希望所有输出语句都运行,而不是所有total += 运行?
  • @Barry。我希望这里有一些解决方法,我可以获取所有输出语句,但只提取最大值。
  • 您要解决的问题是什么?您可以在没有装饰器的情况下轻松编写 MAX() 函数,或者只使用库中存在的函数。装饰器是解决特定问题的工具。它“允许将行为静态或动态添加到单个对象,而不会影响同一类中其他对象的行为。”

标签: c++ design-patterns decorator


【解决方案1】:

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

这就是你得到所有装饰器的总和为 12 的原因(B 特征> + Decorated1 特征> + Decorated2 特征>)。

如果你想继续研究结构模式,如果你想产生预期的结果,你必须初始化 A 类的对象并将其分别发送到所有装饰器类..

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

一个更好的选择是使用创造设计模式

您可以在此处使用 Java 代码查看这些有关设计模式的示例。 https://github.com/pavansn/java-design-patterns

希望对你有帮助

【讨论】:

    【解决方案2】:

    您需要拆分doIt 的功能。您不能在函数中应用增量 并且 做一些特殊的事情并且不同时发生这两种操作。

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

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

    【讨论】:

      猜你喜欢
      • 2016-09-04
      • 2011-02-17
      • 2014-07-07
      • 2011-07-20
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      相关资源
      最近更新 更多