[ PHP ] オブジェクト指向デザイン Bridge パターンの実装サンプル

Pocket

ここでは、PHP を使用してデザインパターンの1つであるブリッジパターンの実装サンプルを掲載しています。

スポンサーリンク

PHP におけるオーバーロード

まず、はじめに注意点として PHP におけるオーバーロードについて押さえておきたい次のポイントがあります。

PHP におけるメソッドのオーバーロードとは、定義されていないメソッドがコールされた場合に呼びだされるメソッドを実装する仕組みのことを指します。他言語で一般的な、パラメータの型や個数が異なる同一名のメソッドを定義することではありません。

紛らわしいので、オーバーロードとは別名にすればよいのにとも思います。

ブリッジパターンの実装例

ブリッジパターンそのものについて確認したい場合は、以下のリンクを参照ください。

次に、Bridge パターンを実装するサンプルスクリプトになります。定義されていないメソッドが呼び出された場合にコールされるオーバーロードメソッド(__call マジックメソッド)を作成している点がポイントです。詳細はサンプル内のコメントを参照ください。

// インターフェース定義
interface BridgeInterface
{
    public function func1($args);
    public function func2();
    public function func3();
}

// 実装クラス
class BridgeImpl implements BridgeInterface
{
    public function func1($args)
    {
        echo 'func1 called, params = ' . $args[0][0] . ',' . $args[0][1];
    }

    public function func2()
    {
        echo 'func2 called';
    }

    public function func3()
    {
        echo 'func3 called';
    }
}

// ブリッジ(橋渡し)クラス
class Bridge
{
    // BridgeInterface
    private $_impl;

    public function __construct($impl)
    {
        // BridgeInterface インターフェースを実装したオブジェクトのみ設定可能
        if (!$impl instanceof BridgeInterface) {
            throw new Exception('not BridgeInterface object');
        }
        $this->_impl = $impl;
    }

    // 実装へのラッパーメソッド
    public function __call($name, $args)
    {
        // メソッドが存在するか確認する
        if(!method_exists($this->_impl, $name)) {
            $msg = 'invalid method call: ' . get_class($this->_impl) . '::' . $name . '() does not exist';
            throw new Exception($msg);
        }
        
        // 実装クラスのメソッドをコール
        return $this->_impl->{$name}($args);
        // または
        //return call_user_func(array($this->_impl, $name), $args);
    }
}

/*
 * 利用者側のコード
 */
try {
    
    // Bridge クラスのインスタンス生成(実装クラスのインスタンスを設定)
    $bridge = new Bridge(new BridgeImpl());
    
    /*
     *  Bridge クラスのオーバーロードメソッドを経由して
     *  実装クラスのメソッドがコールされる
     */    
    $args = array('value1', 'value2');
    $bridge->func1($args);
    $bridge->func2();
    $bridge->func3();
    $bridge->func4(); // exception
    
} catch (Exception $e) {
    var_dump($e->getMessage());
}

// 出力結果
//========================================================
// func1 called, params = value1,value2
// func2 called
// func2 called
//
// string 'invalid method call: BridgeImpl::func4() does not exist' (length=55)
//
参考
スポンサーリンク


Pocket

Leave a Comment

Your email address will not be published. Required fields are marked *