コンセプト
デコレーター パターンを使用すると、構造を変更せずに既存のオブジェクトに新しい機能を追加できます。このタイプのデザイン パターンは構造パターンであり、既存のクラスのラッパーとして機能します。
このパターンは、元のクラスをラップする装飾クラスを作成し、クラス メソッド シグネチャの整合性を維持しながら追加機能を提供します。
UML 図
Role
抽象コンポーネントの役割 (コンポーネント): 追加の責任を受け入れる準備ができているオブジェクトを標準化するオブジェクト インターフェイスを定義します。つまり、これらのオブジェクトに責任を動的に追加できます。
具象コンポーネントの役割 (ConcreteComponent): デコレーターは、機能を追加するために装飾されるクラスを定義します。このクラスのオブジェクトにいくつかの責任を追加できます
抽象デコレータ (Decorator): コンポーネント Component オブジェクトを指すインスタンスを維持し、抽象コンポーネント ロール コンポーネント インターフェイスと一致するインターフェイスを定義します
具象デコレータ ロール (ConcreteDecorator): コンポーネント責任を追加します。
適用可能なシナリオ
オブジェクトに関数を動的に追加する必要があり、これらの関数は動的に取り消すことができます。
いくつかの基本関数の順列と組み合わせによって生成される非常に多くの関数を追加する必要があるため、継承関係が非現実的になります。
サブクラスの生成方法が拡張に使用できない場合。場合によっては、多数の独立した拡張機能があり、それぞれの組み合わせをサポートするために多数のサブクラスが生成され、サブクラスの数が爆発的に増加することがあります。別のケースとしては、クラス定義が非表示になっているか、クラス定義を使用してサブクラスを生成できないことが考えられます。
コード
<?php header('Content-type:text/html;charset=utf-8'); /** * 装饰器模式 */ /** * Interface IComponent 组件对象接口 */ interface IComponent { public function display(); } /** * Class Person 待装饰对象 */ class Person implements IComponent { private $_name; /** * Person constructor. 构造方法 * * @param $name 对象人物名称 */ public function __construct($name) { $this->_name = $name; } /** * 实现接口方法 */ public function display() { echo "装扮者:{$this->_name}<br/>"; } } /** * Class Clothes 所有装饰器父类-服装类 */ class Clothes implements IComponent { protected $component; /** * 接收装饰对象 * * @param IComponent $component */ public function decorate(IComponent $component) { $this->component = $component; } /** * 输出 */ public function display() { if(!empty($this->component)) { $this->component->display(); } } } /** * 下面为具体装饰器类 */ /** * Class Sneaker 运动鞋 */ class Sneaker extends Clothes { public function display() { echo "运动鞋 "; parent::display(); } } /** * Class Tshirt T恤 */ class Tshirt extends Clothes { public function display() { echo "T恤 "; parent::display(); } } /** * Class Coat 外套 */ class Coat extends Clothes { public function display() { echo "外套 "; parent::display(); } } /** * Class Trousers 裤子 */ class Trousers extends Clothes { public function display() { echo "裤子 "; parent::display(); } } /** * 客户端测试代码 */ class Client { public static function test() { $zhangsan = new Person('张三'); $lisi = new Person('李四'); $sneaker = new Sneaker(); $coat = new Coat(); $sneaker->decorate($zhangsan); $coat->decorate($sneaker); $coat->display(); echo "<hr/>"; $trousers = new Trousers(); $tshirt = new Tshirt(); $trousers->decorate($lisi); $tshirt->decorate($trousers); $tshirt->display(); } } Client::test();
実行結果:
コートスニーカー着付け者:Zhang San
Tシャツパンツ着付け者:Li Si