HOME>WEBプログラム覚書>デザインパターン Composite

デザインパターン Composite

Compositeパターンメモ

単体オブジェクトである葉と葉や枝を持つことができる枝オブジェクトを同様に扱うことができる。 ディレクトリツリーのような再帰的なデータ構造を表現できる。

このオブジェクト脳のつくり方では重要なパターンの一つとして取り上げられてました。 サンプルがJAVAですが、最初のほうはJAVAを知らない自分でも理解できるレベルで 書いてあるのでオススメです。

すみません自分は立ち読みです。いつかお金に余裕でたら買います。

ディレクトリツリーを作る

abstract CompositeAPI.php

クライアントはここで 宣言されたメソッド、プロパティのみを利用して プログラムを書く。

add()とview()は枝と葉で実装する。

PHP

  1. <?php
  2. abstract class CompositeAPI
  3. {
  4.     private $name;
  5.     private $lv = null;
  6.     private $prefix = "■";
  7.  
  8.     public function __construct($name, $lv)
  9.     {
  10.         $this->name = $name;
  11.         $this->lv = $lv;
  12.     }
  13.  
  14.     public function getName()
  15.     {
  16.         return $this->name;
  17.     }
  18.  
  19.     public function getLv()
  20.     {
  21.         return $this->lv;
  22.     }
  23.  
  24.     public function getPrefix()
  25.     {
  26.         return $this->prefix;
  27.     }
  28.  
  29.     public function getViewString()
  30.     {
  31.         return str_repeat($this->getPrefix(), $this->getLv()) . $this->name;
  32.     }
  33.  
  34.     public abstract function add(CompositeAPI $obj);
  35.     public abstract function view();
  36. }
  37. ?>

Folder.php

枝にあたるクラス。 add()はCompositeAPIすなわち 枝も葉も格納できるようになっている。

view()は自分のプロパティ表示と、 格納された枝と葉のview()を呼び出す。

PHP

  1. <?php
  2. class Folder extends CompositeAPI
  3. {
  4.     private $files = array();
  5.  
  6.     public function __construct($name, $lv)
  7.     {
  8.         parent::__construct($name, $lv);
  9.     }
  10.  
  11.     public function add(CompositeAPI $obj)
  12.     {
  13.         array_push($this->files, $obj);
  14.     }
  15.  
  16.     public function view()
  17.     {
  18.         printf("<b>%s</b><br />", $this->getViewString());
  19.  
  20.         foreach ($this->files as $file) {
  21.             $file->view();
  22.         }
  23.     }
  24. }
  25. ?>

Folder.php

葉にあたるクラス。 葉は枝も葉も持てないのでadd()は例外を発生させる。

PHP

  1. <?php
  2. class File extends CompositeAPI
  3. {
  4.     public function __construct($name, $lv)
  5.     {
  6.         parent::__construct($name, $lv);
  7.     }
  8.  
  9.     public function add(CompositeAPI $obj)
  10.     {
  11.         throw new Exception("error");
  12.     }
  13.  
  14.     public function view()
  15.     {
  16.         printf("%s<br />", $this->getViewString());
  17.     }
  18. }
  19. ?>

クライアントコード

PHP

  1. <?php
  2. function serch($target, Folder $current)
  3. {
  4.     chdir($target);
  5.  
  6.     foreach (glob("*") as $file) {
  7.         if (is_dir($target . $file)) {
  8.             $current->add($child = new Folder($file, $current->getLv() + 1));
  9.             serch($target . $file . DS, $child);
  10.         } elseif (is_file($target . $file)) {
  11.             $current->add(new File($file, $current->getLv()));
  12.         }
  13.     }
  14.  
  15.     return $current;
  16. }
  17.  
  18. $target = $_SERVER["DOCUMENT_ROOT"] . DS . "sample" . DS;
  19. $root = new Folder("root", 0);
  20.  
  21. $tree = serch($target, $root);
  22. $tree->view();
  23. ?>
実行結果
root
■compass
■■mixins
■■_.scss
■■adjust-font-size-to.css
■■adjust-font-size-to.scss
■■adjust-leading-to.css
■■adjust-leading-to.scss
■■align-content.css
■■align-content.scss
■■align-items.css
■■align-items.scss
■■align-self.css
■■align-self.scss
■■alternating-rows-and-columns.css
■■alternating-rows-and-columns.scss
■■animation-delay.css
■■animation-delay.scss
■■animation-direction.css
■■animation-direction.scss
■■animation-duration.css
■■animation-duration.scss
■■animation-fill-mode.css
■■animation-fill-mode.scss
■■animation-iteration-count.css
■■animation-iteration-count.scss
■■animation-name.css
■■animation-name.scss
■■animation-play-state.css
■■animation-play-state.scss
■■animation-timing-function.css
■■animation-timing-function.scss
■■animation.css
■■animation.scss
■■appearance.css
■■appearance.scss
■■apply-origin.css
■■apply-origin.scss
■■apply-side-rhythm-border.css
■■apply-side-rhythm-border.scss
■■backface-visibility.css
■■backface-visibility.scss
■■background-clip.css
■■background-clip.scss
■■background-image.css
■■background-image.scss
■■background-origin.css
■■background-origin.scss
■■background-size.css
■■background-size.scss
■■background-with-css2-fallback.css
■■background-with-css2-fallback.scss
■■background.css
■■background.scss
■■bang-hack.css
■■bang-hack.scss
■■baseline-grid-background.css
■■baseline-grid-background.scss
■■border-bottom-left-radius.css
■■border-bottom-left-radius.scss
■■border-bottom-radius.css
■■border-bottom-radius.scss
■■border-bottom-right-radius.css
■■border-bottom-right-radius.scss
■■border-corner-radius.css
■■border-corner-radius.scss
■■border-image.css
■■border-image.scss
■■border-left-radius.css
■■border-left-radius.scss
■■border-radius.css
■■border-radius.scss
■■border-right-radius.css
■■border-right-radius.scss
■■border-top-left-radius.css
■■border-top-left-radius.scss
■■border-top-radius.css
■■border-top-radius.scss
■■border-top-right-radius.css
■■border-top-right-radius.scss
■■box-shadow.css
■■box-shadow.scss
■■box-sizing.css
■■box-sizing.scss
■■break-after.css
■■break-after.scss
■■break-before.css
■■break-before.scss
■■break-inside.css
■■break-inside.scss
■■pattern.gif
■■pic.png
■test.scss
■file_find
■element.xsl
■foreach.xml
■■img
■■aoc_pak.gif
■■contact.jpg
■■ct_01.jpg
■■ct_02.jpg
■■ct_03.jpg
■■ct_04.jpg
■■lv2
■■foreach.xml
■■foreach.xsl
■■lv2file_find.php
■■■lv3
■■■test1.php
■■■test2.php
■■■test3.php
■■test.php
■■test.txt
■■test1.php
■■test2.php
■■test3.php
■test.php
■test.txt
■test1.php
■test2.php
■test3.php
■php
■■pg
■■session.php
■react_webpack
■■_dev
■■■archive
■■■App.js
■■■index.js
■■■front-page
■■■App.js
■■■index.js
■■package-lock.json
■■package.json
■■webpack.config.js
■archive.php
■front-page.php
■■js
■■archive.bundle.js
■■front-page.bundle.js
■sidemenu
■index.php
■jquery.php
■jquery2.html
■menu.gif
■text
■passwd.txt
■xml
■■afi
■■job.xml
■element.xml
■element.xsl
■foreach.xml
■foreach.xsl
■■sitemap
■■sitemap.xml
■■web_design.xml

デザインパターン自体はなんとか理解できますが 実際に使えてるかというと全然使えてないのが現実。

愛読書である

に書かれてる

  • 具体的なモノではなく抽象化されたモノを扱う。
  • インターフェイスに対してプログラムする。

ができるようになるともっとわかりやすい 人に優しいスクリプトが書けるようになる気がする。

遠い道のりになりそうですが・・・

投稿日 2009年3月26日 18:34
カテゴリ PHP
タグ サンプルコード | デザインパターン
トラックバック URL http://www.kantenna.com/cgi-bin/mt504/mt-tb.cgi/1172

コメント

コメントする
Name
Email Address
URL