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でデザインパターン(Bridge編)

zip形式 tgz形式

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

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

今回は、Bridgeパターンで「機能と実装の階層を分ける」パターンです(以下のクラス図を参照)。

Bridgeパターンのクラス図

Abstraction側が機能、Implementor側が実装の各階層になります。Abstraction側は継承により新たなメソッドを追加することで機能拡張を行い、Implementor側はTemplate Methodパターンになっていて、複数の実装を持つことができます。そして、委譲によりそれぞれの階層を結びつけています。このBridgeパターンは、Windows版・Linux版など同じ機能をOS毎に実装しなければならない場合、などに見かけるパターンです。

今回のサンプルは、携帯向け(i-mode版とEZWeb版)の画面を表示する、というもので、表示形式をAbstraction側、表示の実装部分をImplementor側にそれぞれ分けています。

以下がサンプルコードで、動作確認はPHP4.3.0です。ページの先頭にあるリンクから、サンプルスクリプトをダウンロードできます。

●PageDisplay.phl

<?php
/**
 * 機能階層の基底クラス
 */
class PageDisplay
{
    /**
     * 実装側のインスタンス
     */
    var $impl_;

    /**
     * コンストラクタ
     */
    function PageDisplay($impl)
    {
        $this->impl_ = $impl;
    }

    /**
     * Content-Typeを出力する
     */
    function printContentType()
    {
        header("Content-Type: " . $this->impl_->getContentType());
    }

    /**
     * ページヘッダを出力する
     */
    function printHeader() { $this->impl_->printHeader(); }

    /**
     * タイトルを出力する
     */
    function printTitle() { $this->impl_->printTitle(); }

    /**
     * データを出力する
     */
    function printData() { $this->impl_->printData(); }

    /**
     * ページフッタを出力する
     */
    function printFooter() { $this->impl_->printFooter(); }

    /**
     * 区切り線を出力する
     */
    function printBorder() { $this->impl_->printBorder(); }

    /**
     * 画面を表示する
     */
    function display()
    {
        $this->printContentType();
        $this->printHeader();
        $this->printTitle();
        $this->printBorder();
        $this->printData();
        $this->printFooter();
    }
}
?>

●MobilePage.phl

<?php
require_once("jp/ne/hi_ho/pat/dimension/Abstract.phl");
?>
<?php
/**
 * 実装階層の基底クラス
 */
class MobilePage
{
    /**
     * Content-Typeを出力する
     */
    function printContentType() { Abstract::set("open"); }

    /**
     * ページヘッダを出力する
     */
    function printHeader() { Abstract::set("printHeader"); }

    /**
     * タイトルを出力する
     */
    function printTitle() { Abstract::set("printTitle"); }

    /**
     * データを出力する
     */
    function printData() { Abstract::set("printData"); }

    /**
     * ページフッタを出力する
     */
    function printFooter() { Abstract::set("printFooter"); }

    /**
     * 区切り線を出力する
     */
    function printBorder() { Abstract::set("printBorder"); }
}
?>

●ImodePage.phl

<?php
require_once("MobilePage.phl");
?>
<?php
/**
 * 実装階層の具象クラス
 */
class ImodePage extends MobilePage
{
    var $TITLE = "Bridgeパターンのテスト";

    /**
     * Content-Typeを出力する
     */
    function getContentType() { return "text/html"; }

    /**
     * ページヘッダを出力する
     */
    function printHeader()
    {
        echo "<html><title>" . $this->TITLE . "</title><body>";
    }

    /**
     * タイトルを出力する
     */
    function printTitle()
    {
        echo "<center>" . $this->TITLE . "</center>";
    }

    /**
     * データを出力する
     */
    function printData()
    {
        echo "何らかのデータです。<br>"
           . "何らかのデータです。<br>";
    }

    /**
     * ページフッタを出力する
     */
    function printFooter() { echo "</body></html>"; }

    /**
     * 区切り線を出力する
     */
    function printBorder() { echo "<hr>"; }
}
?>

●Bridge.php

<?php
<?php
require_once("PageDisplay.phl");
require_once("CopyRightPageDisplay.phl");
require_once("MobilePage.phl");
require_once("ImodePage.phl");
require_once("EzwebPage.phl");
?>
<?php
    /**
     * main
     */
    $pd = new PageDisplay(new ImodePage());
//    $pd = new PageDisplay(new EzwebPage());
//    $pd = new CopyRightPageDisplay(new ImodePage());
//    $pd = new CopyRightPageDisplay(new EzwebPage());

    $pd->display();
?>

本来であれば、Abstractionに相当するPageDisplayクラスのコンストラクタで、正しくImplementor型のオブジェクトが渡されたかどうかをチェックする必要がありますが、ちょっと手を抜いてます。。。PHPでは基本的に型がありませんので、こちらにあるようなinstanceOfメソッドを使って実装する感じになるでしょうか?



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