Do You PHP?    
Search Engine Optimization  php5 powerd  Valid XHTML 1.0!  Valid CSS!  このサイトのはてなブックマーク数 



last updated
2005/05/25

counter hits
since 1999/11/06


PHP4でデザインパターン(Builder編)

zip形式 tgz形式

オブジェクト指向についてはまだまだ勉強中ですが、「PHPでGoFのデザインパターンを実装したら、どんな感じになるんだろ?」と思ってしまったので、ちょっとずつやってみることにしました。

caution間違いやご意見がありましたら、遠慮なくツッコミを入れてくださいm(_"_)m

今回は、Builderパターンで「構造を持ったインスタンスを組み上げる」パターンです(以下のクラス図を参照)。簡単な説明ですが、クライアントから直接Builderを呼び出すのではなく、Directorを呼び出します。こうすることでクライアントはBuilderを意識する事がなくなり、ConcreteBuilderを差し替える事ができるようになります。また、BuilderとConcreteBuilderの部分がTemplate Methodパターンになっています。

Builderパターンのクラス図

今回のサンプルは、Template Methodパターンで使用したサンプルを元に作ってみました。あまり良いサンプルではないかも。。。

以下がサンプルコードです。また、Abstractクラスなどを含めたスクリプトコードは、上のリンクからダウンロードできます。

●Builder.php

<?php
require_once("jp/ne/hi_ho/pat/dimension/Abstract.phl");
?>
<?php
class Director
{
    var $builder_;

    /**
     * リソースを開く
     */
    function Director($builder)
    {
        $this->builder_ = $builder;
    }

    /**
     * データを作成し、返す
     */
    function construct()
    {
        $this->builder_->open();
        $this->builder_->get();
        $this->builder_->make();
        $this->builder_->close();

        return $this->builder_->getResult();
    }
}

class Builder
{
    /**
     * リソースを開く
     */
    function open() { Abstract::set("open"); }

    /**
     * データを取得する
     */
    function get() { Abstract::set("get"); }

    /**
     * 結果を作成する
     */
    function make() { Abstract::set("make"); }

    /**
     * リソースを閉じる
     */
    function close() { Abstract::set("close"); }

    /**
     * 結果を返す
     */
    function getResult() { Abstract::set("getResult"); }

}

/**
 * DBデータの表示
 */
class DbBuilder extends Builder
{
    // 結果文字列を格納するバッファ
    var $buf_;

    var $conn_;
    var $stmt_;
    var $data_;
    var $rows_;

    function open()
    {
        $this->conn_ = OCILogon("scott", "tiger", "orcl");
        $this->buf_ = "";
    }

    function get()
    {
        $this->stmt_ = OCIParse($this->conn_, "SELECT * FROM emp");
        OCIExecute($this->stmt_);
        $this->rows_ = OCIFetchStatement($this->stmt_, $this->data_);
    }

    function make()
    {
        $this->buf_ .= "<table border=\"1\">";
        $this->buf_ .= "<tr>";
        while (list( $key, $val ) = each( $this->data_ ) ) {
            $this->buf_ .= "<th>$key</th>";
        }
        $this->buf_ .= "</tr>";

        for ( $i = 0; $i < $this->rows_; $i++ ) {
            reset($this->data_);
            $this->buf_ .= "<tr>";
            while ( $column = each($this->data_) ) {
                $data = $column['value'];
                $this->buf_ .= "<td>$data[$i]</td>";
            }
            $this->buf_ .= "</tr>";
        }
        $this->buf_ .= "</table>";
    }

    function close()
    {
        OCIFreeStatement($this->stmt_);
        OCILogOff($this->conn_);
    }

    function getResult() { return $this->buf_; }
}
/**
 * ファイルデータの表示
 */
class FileBuilder extends Builder
{
    var $fp_;
    var $buf_;

    function open()
    {
        $this->fp_ = fopen(__FILE__, "r");
        $this->buf_ = "";
    }

    function get()
    {
        while (!feof($this->fp_)) {
            $this->buf_ .= fgets($this->fp_, 4096);
        }
    }

    function make()
    {
        $this->buf_ = highlight_string($this->buf_);
    }

    function close()
    {
        fclose($this->fp_);
    }

    function getResult() { return $this->buf_; }
}
?>
<?php
    /**
     * main
     */
    $arr = array(new DbBuilder(), new FileBuilder());
    foreach ($arr as $index => $obj) {
        $director = new Director($obj);
        echo $director->construct();
        echo "<hr>";
    }
?>

出力結果はこちらのようになります。



About This Site |  Privacy Policy |  Contact
Copyright © 1999 - 2005 by Hideyuki SHIMOOKA all rights reserved.