2009年03月26日 18:34

デザインパターン Composite

| http://www.kantenna.com/cgi-bin/mt/mt-tb.cgi/450

Compositeパターンメモ

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

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

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

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

abstract CompositeAPI.php

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

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


abstract class CompositeAPI
{
    private $name;
    private $lv = null;
    private $prefix = "■";

    public function __construct($name, $lv)
    {
        $this->name = $name;
        $this->lv = $lv;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getLv()
    {
        return $this->lv;
    }

    public function getPrefix()
    {
        return $this->prefix;
    }

    public function getViewString()
    {
        return str_repeat($this->getPrefix(), $this->getLv()) . $this->name;
    }

    public abstract function add(CompositeAPI $obj);
    public abstract function view();
}

Folder.php

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

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


class Folder extends CompositeAPI
{
    private $files = array();

    public function __construct($name, $lv)
    {
        parent::__construct($name, $lv);
    }

    public function add(CompositeAPI $obj)
    {
        array_push($this->files, $obj);
    }

    public function view()
    {
        printf("<b>%s</b><br />", $this->getViewString());

        foreach ($this->files as $file) {
            $file->view();
        }
    }
}

Folder.php

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


class File extends CompositeAPI
{
    public function __construct($name, $lv)
    {
        parent::__construct($name, $lv);
    }

    public function add(CompositeAPI $obj)
    {
        throw new Exception("error");
    }

    public function view()
    {
        printf("%s<br />", $this->getViewString());
    }
}

クライアントコード


function serch($target, Folder $current)
{
    chdir($target);

    foreach (glob("*") as $file) {
        if (is_dir($target . $file)) {
            $current->add($child = new Folder($file, $current->getLv() + 1));
            serch($target . $file . DS, $child);
        } elseif (is_file($target . $file)) {
            $current->add(new File($file, $current->getLv()));
        }
    }

    return $current;
}

$target = $_SERVER["DOCUMENT_ROOT"] . DS . "sample" . DS;
$root = new Folder("root", 0);

$tree = serch($target, $root);
$tree->view();

実行結果
root
■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
■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

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

愛読書である

PHPによるデザインパターン入門

著者 : 下岡 秀幸 / 金額 : ¥ 3,150

に書かれてる

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

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

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

デザインパターン Compositeタグ:

トラックバック

  • http://www.kantenna.com/cgi-bin/mt/mt-tb.cgi/450
[情報備忘録]2010年02月13日 03:15
[PHP]これはPHP初心者は絶対読むべき!!・・・だとおもう、極上のリソース
これはPHP初心者は絶対読むべき!!・・・だとおもう、極上のリソース
コメント (0)
コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)





この情報を登録しますか?


先月アクセスが多かったページ