ラーメンの話
ラーメン屋ではラーメンを販売しています。ラーメンは小鉢と大鉢に分かれています。小鉢は 6 元、大鉢は 6 元です。大鉢は6元、9元。さらに、牛肉を追加する場合は6元、卵は1元、大きなステーキは5元、カリカリライス1個は1元です。従来の書き方で価格の異なるラーメンを設定する場合、8項目(ラーメンの数×サイドメニューの数)を記述する必要があります。ヌードル ショップが新しいポーション サイズ (ミディアム ボウル) を導入した場合、4 つの新しいカテゴリを追加する必要があります。これにより、クラス爆発という問題が発生します。
私の以前の記事https://www.php.cn/php-weizijiaocheng-457250.htmlを読んだ方は、ブリッジ モードを理解した後、この問題が解決できると感じるでしょう。解決するにはブリッジモードを使用してください。大きく分けて麺類とおかずの2つに分けます。
以下では、ブリッジ モードを使用して上記の問題を解決します。コードは次のとおりです:
interface INoodle { function cost (); function desc (); } class BigNoodle implements INoodle { private $cost = 9.0; private $dish = null; public function __construct(IDish $dish) { $this->dish = $dish; } public function cost() { return $this->cost + $this->dish->cost(); } public function desc() { return $this->dish->desc() . '大碗拉面'; } } class SmallNoodle implements INoodle { private $cost = 6.0; private $dish = null; public function __construct(IDish $dish) { $this->dish = $dish; } public function cost() { return $this->cost + $this->dish->cost(); } public function desc() { return $this->dish->desc() . '小碗拉面'; } } interface IDish { function cost (); function desc (); } class Beef implements IDish { public function cost () { return 6; } public function desc() { return '牛肉'; } } class Crust implements IDish { public function cost () { return 1; } public function desc() { return '锅巴'; } } class Egg implements IDish { public function cost () { return 1; } public function desc() { return '鸡蛋'; } }
Decorator モード
ブリッジ モードを使用する これにより、疑似爆発の問題は解決されますが、麺類を食べに行くときに、おかずが必要なく麺だけの場合や、複数のおかずが必要な場合があることもご存知でしょう。牛肉ラーメンのボウルにカリカリビーフン 3 個と卵 2 個を加えます。この要件では、ブリッジ モードは使用できません。この問題を解決するには、別の構造設計パターンであるデコレーター パターンを使用できます。
装飾パターンは、動作を含む特別なカプセル化オブジェクトにオブジェクトを配置することで、新しい動作を元のオブジェクトにバインドできる構造設計パターンです。
デコレータ パターンを理解するには、人形マトリョーシカを想像してください。
人形の各セットは、人形の装飾オブジェクトを追加することに相当します。 。実行時には、最も外側の装飾オブジェクト (外側のレイヤー) が実行され、その後レイヤーごとに実行されます。今は意味が分からないかもしれませんが、以下の内容を読んだ後にもう一度この文章を読むと理解できるかもしれません。
私は UML クラス図を自分で描きましたが、少し見苦しいので、誰もがそれをクリックするだけです
コードの実装
abstract class Noodles { abstract function cost (); abstract function desc (); } class BigNoodle extends Noodles { private $cost = 9.0; public function cost() { return $this->cost; } public function desc() { return '大碗拉面'; } } class SmallNoodle extends Noodles { private $cost = 6.0; public function cost() { return $this->cost; } public function desc() { return '小碗拉面'; } } abstract class NoodlesDecorator extends Noodles { } class Beef extends NoodlesDecorator { private $desc = '牛肉'; private $cost = 6.0; protected $noodles = null; public function __construct(Noodles $noodels) { $this->noodles = $noodels; } public function cost () { return $this->cost + $this->noodles->cost(); } public function desc () { return $this->desc . $this->noodles->desc(); } } // egg、curst类代码省略,除了属性值不一样基本和Beef一致
テストコードは次のとおりです
$noodles = new BigNoodle(); $beefBigNoodles = new Beef($noodles); $eggBeffBigNoodles = new Egg($beefBigNoodles); echo $eggBeffBigNoodles->desc(); echo $eggBeffBigNoodles->cost() . '元';
結果出力: 卵と牛肉のラーメン大盛り 16 元
概要
質問について考えてみますが、ここでラーメンの量がデコレータ オブジェクトとして使用されていないのはなぜですか?考えてみてください、あなたはラーメン大盛りと小盛りを注文しますか?
#デコレータ パターンの機能
以上がデコレータ パターンとは何ですか?ブリッジ パターンとの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。