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



last updated
2002/05/12

counter hits
since 1999/11/06


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

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

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

今回は、Template Methodパターンで「親クラスで処理の枠決めを行い、サブクラスで具体的な実装を行う」パターンです(以下のクラス図を参照)。

Template Methodパターンのクラス図

クラス同士の関係はかなり単純で、抽象クラスとそのサブクラスだけで構成されます。今回のサンプルは、練習問題にも出てきそうな

  • リソースの取得
  • データの取得
  • データの表示
  • リソースの解放

というもので、お決まりのファイル入力とDB連携をやっています。上のクラス図との関係は、以下のようになります。

  • AbstractClass => Template
  • ConcreteClass => DbDisplay/FileDisplay

以下がサンプルコードです。

●TemplateMethod.php

<?php
class Template
{
    /**
     * リソースを開く
     */
    function open()
    {
    }

    /**
     * データを取得する
     */
    function get()
    {
    }

    /**
     * 結果を表示する
     */
    function show()
    {
    }

    /**
     * リソースを閉じる
     */
    function close()
    {
    }

    /**
     * 処理の枠組み
     */
    function process()
    {
        $this->open();
        $this->get();
        $this->show();
        $this->close();
    }
}

/**
 * DBデータの表示
 */
class DbDisplay extends Template
{
    var $conn_;
    var $stmt_;
    var $data_;
    var $rows_;

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

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

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

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

    function close()
    {
        OCIFreeStatement($this->stmt_);
        OCILogOff($this->conn_);
    }
}
/**
 * ファイルデータの表示
 */
class FileDisplay extends Template
{
    var $fp_;
    var $buf_;

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

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

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

    function close()
    {
        fclose($this->fp_);
    }
}
?>
<?php
    /**
     * main
     */
    $arr = array(new DbDisplay(), new FileDisplay());
    foreach ($arr as $index => $obj) {
        $obj->process();
        echo "<hr>";
    }
?>

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

PHPではJavaと異なり、abstractなメソッドの実装がConcreteClassで強制されないので、極端な話、AbstractClassに相当するクラスがなくても問題ないですが、あった方がわかりやすいと思います(手間ですが。。。)。

memo[2002/03/09] こちらに「abstractメソッドの実装を強制」させることについてまとめています



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