プログラミングの目的: デコレータ パターンとその使用法を理解すること。
オブジェクトに追加の役割を動的に追加する Decorator は、機能を追加するという点で、サブクラスを生成するよりも柔軟です。[DP]
デコレータ パターンは、実行時にオブジェクトに新しい動作を動的に追加できる構造設計パターンです。このパターンは、元のオブジェクトを含むラッパーを作成し、実行時に新しい動作を追加することによって実装されます。このプロセスでは、元のオブジェクトのコードを変更する必要がないため、装飾モードは非常に柔軟なモードです。
デコレータ パターンの C++ 実装は次のとおりです。
まず、新しい動作を追加するオブジェクトを表す基本コンポーネント クラスを定義する必要があります。この例では、単純な文字列クラスを例として取り上げます。
class Component {
public:
virtual ~Component() {}
virtual std::string operation() const = 0;
};
次に、具象コンポーネント クラスを実装する必要があります。この例では、単純な文字列クラスを例として取り上げます。
class ConcreteComponent : public Component {
public:
std::string operation() const override {
return "ConcreteComponent";
}
};
次に、具体的なコンポーネントをラップし、新しい動作を追加するデコレータ クラスを定義する必要があります。
class Decorator : public Component {
public:
Decorator(Component* component) : component_(component) {}
std::string operation() const override {
return component_->operation();
}
protected:
Component* component_;
};
最後に、具体的なデコレータ クラスを実装して、新しい動作を追加できます。
class ConcreteDecoratorA : public Decorator {
public:
ConcreteDecoratorA(Component* component) : Decorator(component) {}
std::string operation() const override {
return "ConcreteDecoratorA(" + Decorator::operation() + ")";
}
};
class ConcreteDecoratorB : public Decorator {
public:
ConcreteDecoratorB(Component* component) : Decorator(component) {}
std::string operation() const override {
return "ConcreteDecoratorB(" + Decorator::operation() + ")";
}
};
この例では、2 つの具象デコレータ クラス ConcreteDecoratorA と ConcreteDecoratorB を定義します。これらのデコレーター クラスはすべて Decorator クラスから継承され、そのコンストラクターはすべてコンポーネント オブジェクトへのポインターを受け入れ、それをクラス メンバー変数に格納します。これらの具体的なデコレータ クラスでは、新しい動作を追加するためにアクション メソッドをオーバーライドします。
ここで、これらのクラスを使用して、複数の動作を持つオブジェクトを作成できます。
Component* component = new ConcreteComponent();
Component* decoratorA = new ConcreteDecoratorA(component);
Component* decoratorB = new ConcreteDecoratorB(decoratorA);
std::cout << decoratorB->operation() << std::endl;
この例では、最初に具体的なコンポーネント オブジェクトを作成します。次に、それを ConcreteDecoratorA で装飾し、結果を DecoratorA 変数に保存します。次に、decoratorA を ConcreteDecoratorB で装飾し、結果を DecoratorB 変数に保存します。最後に、decoratorB の操作の結果を出力します。これには、追加されたすべての行が含まれます。
ために。
この例で、decoratorB の演算結果を出力すると、次のようになります。
ConcreteDecoratorB(ConcreteDecoratorA(ConcreteComponent))
これは、最初に ConcreteComponent を ConcreteDecoratorA として修飾し、次に結果を ConcreteDecoratorB として修飾するため、最終結果には追加されたすべての動作が含まれます。
デコレーション モードを使用する場合は、デコレータ オブジェクトをあまりにも多く作成しないようにする必要があることに注意してください。そうしないと、コードの保守が困難になる可能性があります。さらに、デコレータ クラスの継承構造を慎重に設計して、デコレータ クラス間の関係が明確かつ明確になるようにする必要もあります。