Decorator パターンの概念
元のクラス ファイルを変更せず、継承を使用せずに、オブジェクトの機能を動的に拡張します。ラッピング オブジェクト、つまり装飾を作成することで、実際のオブジェクトをラップします。
デコレータパターンの特徴
1. 装飾されたオブジェクトは実際のオブジェクトと同じインターフェースを持ちます。このようにして、クライアント オブジェクトは実際のオブジェクトと同じ方法で装飾されたオブジェクトと対話できます。
2. 装飾されたオブジェクトには、実際のオブジェクトへの参照が含まれています
3. 装飾されたオブジェクトは、クライアントからのすべてのリクエストを受け入れます。これらのリクエストを実際のオブジェクトに転送します。
4. 装飾オブジェクトは、これらのリクエストを転送する前または後に、いくつかの追加機能を追加できます。これにより、特定のオブジェクトの構造を変更することなく、実行時に追加の機能を外部から追加できるようになります。オブジェクト指向設計では、通常、特定のクラスの機能拡張は継承を通じて実装されます。
適用性
1. クラスの機能を拡張するか、クラスに追加の責任を追加する必要があります。
2. オブジェクトに関数を動的に追加する必要があり、これらの関数は動的に取り消すことができます。
3. いくつかの基本関数の順列と組み合わせによって生成される非常に多くの関数を追加する必要があり、継承関係が非現実的になります。
4. サブクラスの生成方法が拡張に使用できない場合。場合によっては、多数の独立した拡張機能があり、それぞれの組み合わせをサポートするために多数のサブクラスが生成され、サブクラスの数が爆発的に増加することがあります。別のケースとしては、クラス定義が非表示になっているか、クラス定義を使用してサブクラスを生成できないことが考えられます。
利点
1. Decorator パターンと継承関係の目的はオブジェクトの機能を拡張することですが、Decorator は継承よりも高い柔軟性を提供できます。2. さまざまな特定の装飾クラスとこれらの装飾クラスの配置と組み合わせを使用することにより、デザイナーはさまざまな動作の多くの組み合わせを作成できます。
欠点
1. この機能は継承よりも柔軟ですが、より複雑になることも意味します。
2. 装飾モードを多用すると、デザイン内に多数の小さなクラスが生成され、プログラムが非常に複雑になります。
3. デコレーション モードは、抽象コンポーネント (コンポーネント) 型のプログラミング用です。ただし、特定のコンポーネント用にプログラミングしている場合は、アプリケーション アーキテクチャとデコレータが適切かどうかを再考する必要があります。もちろん、コンポーネント インターフェイスを変更したり、新しいパブリック動作を追加したり、「半透明」デコレータ モードを実装したりすることもできます。実際のプロジェクトでは最善の選択をしてください。
デザイン原則
1. 合成をより多く使用し、継承を減らします。
2. クラスは拡張を受け入れ、変更を受け入れないように設計される必要があります。
デコレータ パターン
インスタンス
<?php//抽象接口类interface IDecorator{ function sayMsg();}//具体装饰类1class decorator1 implements IDecorator{ function sayMsg(){ echo "增加功能1"; }}//具体装饰类2class decorator2 implements IDecorator{ function sayMsg(){ echo "增加功能2"; }}class MailTest{ private $decorators; function addDecorator(IDecorator $decorator){ $this->decorators[] = $decorator; } function addExtraFunction(){ foreach ($this->decorators as $decorator) { $decorator->sayMsg(); } } function test(){ $this->addExtraFunction(); echo "I am test"; }}$mailTest = new MailTest();$decorator1 = new decorator1();$decorator2 = new decorator2();$mailTest->addDecorator($decorator1);$mailTest->addDecorator($decorator2);$mailTest->test();