コンポジット パターン

Composite Pattern

Composite パターン | デザインパターン

2022年9年24日
デザインパターン Composite PHP
...

オライリージャパンによる Head First シリーズ デザインパターン(第2版)第9章 Composite パターンを、PHPで書き直してみようという試みです。

MenuItem.php

 
namespace Composite;

class MenuItem extends MenuComponent {

  public string $name;
  public string $description;
  public bool $vegetarian;
  public float $price;

  public function __construct(string $name, string $description, bool $vegetarian, float $price) {

    $this->name = $name;
    $this->description = $description;
    $this->vegetarian = $vegetarian;
    $this->price = $price;

  }

  public function getName() : string {

    return $this->name;

  }

  public function getDescription() : string {

    return $this->description;

  }

  public function getPrice() : float {

    return $this->price;

  }

  public function isVegetarian() : bool {

    return $this->vegetarian;

  }

  public function print() : void {

    echo self::getName();
    echo (self::isVegetarian() ? '(v)' : null);
    echo '、' . self::getPrice() . "\n";
    echo ' -- ' . self::getDescription() . "\n";

  }

}
 

Menu.php

 
namespace Composite;

class Menu extends MenuComponent {

  public array $menuComponents = [];
  public string $name;
  public string $description;

  public function __construct(string $name, string $description) {

    $this->name = $name;
    $this->description = $description;

  }

  public function add(MenuComponent $menuComponent) : void {

    $this->menuComponents[] = $menuComponent;

  }

  public function remove(int $i) : void {

    unset($this->menuComponents[$i]);

  }

  public function getChild(int $i) : MenuComponent {

    return $this->menuComponents[$i];

  }

  public function getName() : string {

    return $this->name;

  }

  public function getDescription() : string {


    return $this->description;

  }

  public function print() : void {

    echo "\n" . self::getName();
    echo '、' . self::getDescription() . "\n";
    echo '-------------------------' . "\n";

    foreach($this->menuComponents as $menuComponent) {

      $menuComponent->print();

    }

  }
 

MenuComponent.php

 
namespace Composite;

abstract class MenuComponent {

  public function add(MenuComponent $menuComponent) : void {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function remove(int $i) : void {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function getChild(int $i) : MenuComponent {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function getName() : string {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function getDescription() : string {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function getPrice() : float {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function isVegetarian() : bool {

    throw new Exception('UnsupportedOperationException',500);

  }

  public function print() : void {

    throw new Exception('UnsupportedOperationException',500);

  }

}
 

Waitress.php

 
namespace Composite;

class Waitress {

  public MenuComponent $allMenus;

  public function __construct(MenuComponent $allMenus) {

    $this->allMenus = $allMenus;

  }

  public function printMenu() : void {

    $this->allMenus->print();

  }

}
 

index.php

  

出力結果

 
  すべてのメニュー、全てを統合したメニュー
  -------------------------

  パンケーキハウスメニュー、朝食
  -------------------------
  K&Bのパンケーキ朝食(v)、2.99
   -- スクランブルエッグとトースト付きパンケーキ
  いつものパンケーキ朝食、2.99
   -- 卵焼きとソーセージ付きパンケーキ
  ブルーベリーパンケーキ(v)、3.49
   -- 新鮮なブルーベリーを使ったパンケーキ
  ワッフル(v)、3.59
   -- ブルーベリーかいちごの好きな方を乗せたワッフル

   食堂メニュー、昼食
  -------------------------
  ベジタリアンBTL(v)、2.99
   -- レタス、トマト、(フェイク)ベーコンを挟んだ小麦パンサンドイッチ
  BLT、2.99
   -- レタス、トマト、ベーコンを挟んだ小麦パンサンドイッチ
  本日のスープ、3.29
   -- ポテトサラダを添えた本日のスープ
  Hot Dog、3.05
   -- ザワークラウト、レリッシュ、玉ねぎ、チーズを挟んだホットドッグ
  パスタ(v)、3.89
   -- マリナラソーススパゲッティとサワードウパン


  デザートメニュー、もちろんデザート!
  -------------------------
  アップルパイ(v)、1.59
   -- バニラアイスクリームをのせたフレーク上生地のアップルパイ
  チーズケーキ(v)、1.99
   -- チョコレートグラハム生地のクリーミーなニューヨークチーズケーキ
  シャーベット(v)、1.89
   -- ラズベリーシャーベットとライムシャーベット

   カフェメニュー、夕食
  -------------------------
  野菜バーガーとフライドポテト(v)、3.99
   -- 小麦パンにレタスとトマトを挟んだ野菜バーガーとフライドポテト
  本日のスープ、2.99
   -- サラダがついた本日のスープ
  ブリトー(v)、4.29
   -- インゲン豆、サルサ、グアカモーレ入りの大きなブリトー
 

だてめがね
...
©️ ponpocopy

とある企業で社内SEをしています。 自身の学びが誰かの為になれば、という想いで日々ブログを更新中。 PHP(CakePHP・Laravel・FuelPHP), Pyhotn(Django・Flask), C#(ASP.NET、Unity) が好きです。