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

Pocket

オブジェクト指向デザインパターンの1つである Bridge パターンでは、 実処理部と呼出し側の間の橋渡しをするクラスを用意して実装を隠蔽します。具体的には、同一インターフェースを実装したクラスを呼び出すラッパクラスを実装することであると言えるでしょう。

スポンサーリンク


PHP での Bridge パターン実装サンプル

FTP転送とSMBファイル転送をBuilderパターンで実装する」で使用したコードを Bridge パターンで書き直したコードが以下のサンプルになります。 Bridge パターンでは、実処理を実装した別クラスに処理を委譲している点がポイントです。詳細はサンプル内のコメントも参照ください。

// ファイル転送 実装 インターフェース
interface fileSendInterface
{
    public function open();
    public function send($filepath);
    public function close();
}

// FTP ファイル転送の実装
class ftpFileSend implements fileSendInterface
{
    private $_conn;

    public function open()
    {
        $this->_conn = @ftp_connect('接続先');
        
        if($this->_conn == false) { return false; }
        return @ftp_login($this->_conn, 'user', 'password');
    }

    public function send($local_filepath)
    {
        if($this->_conn == false) { return false; }
        
        $remote_filename = basename($local_filepath);
        return @ftp_put($this->_conn, $remote_filename, $local_filepath, FTP_ASCII);
    }

    public function close()
    {
        if($this->_conn == false) { return false; }
        return @ftp_close($this->_conn);
    }
}

// SMB ファイル転送の実装
class smbFileSend implements fileSendInterface
{
    const REMOTE_DIR_PATH = '/path/to/remote/dir';

    public function open()
    {
        // 転送先ディレクトリがあるか確認する
        return is_dir(self::REMOTE_DIR_PATH);
    }

    public function send($local_filepath)
    {
        $remote_filepath = self::REMOTE_DIR_PATH . '/' . basename($local_filepath);
        return copy($local_filepath, $remote_filepath);
    }

    public function close()
    {
        return true;
    }
}

/*
 * Bridge クラス
 * 実際の処理が実装されているクラスに処理を委譲するラッパークラス
 */
class fileSend
{
    // fileSendInterface
    private $_impl;

    public function __construct($impl)
    {
        // fileSendInterface インタフェース以外は実装クラスとして
        // 受け付けない
        if (!$impl instanceof fileSendInterface) {
            throw new Exception('not fileSendInterface object');
        }
        $this->_impl = $impl;
    }

    // 実装クラスを呼び出すラッパー
    public function open()
    {
        return $this->_impl->open();
    }

    // 実装クラスを呼び出すラッパー
    public function send($filepath)
    {
        return $this->_impl->send($filepath);
    }

    // 実装クラスを呼び出すラッパー
    public function close()
    {
        return $this->_impl->close();
    }
}

上記のクラスは以下のように使用します。

$filepath = '/path/to/local/file';

$impl = 'ftp';

if($impl == 'ftp') {
    // FTP でファイルを送信する場合
    $send = new fileSend(new ftpFileSend());
} else {
    // SMB でファイルを送信する場合
    $send = new fileSend(new smbFileSend());
}

/*
 * fileSend クラスはラッパであり、具体的な実装方法は知らない
 * 処理手順は利用者が制御する
 */
$send->open();
$send->send($filepath);
$send->close();
参考

 

スポンサーリンク

Pocket

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>