もくじ
使いどころ
既存のクラスに変更を加えたいが、直接ソースの変更を行いたくない。
WatchYoukai.class.php
<?php /** * 指定されたファイルを表示するクラスです */ class WatchYoukai { private $filename; public function __construct($filename_) { if( !is_readable($filename_) ) { throw new Exception("エラー:{$filename_}は開くことが出来ません。"); } $this->filename = $filename_; } /** * ファイルを表示させます */ public function showPlain() { echo "<pre>"; echo htmlspecialchars(file_get_contents($this->filename), ENT_QUOTES, mb_internal_encoding()); echo "</pre>"; } /** * ファイルをハイライトで表示させます */ public function showHighLight() { highlight_file($this->filename); } }
client.php
<?php require_once 'WatchYoukai.class.php'; try{ $youkaiObj = new WatchYoukai('./WatchYoukai.class.php'); }catch(Excetion $e){ die($e->getMessage()); } $youkaiObj->showPlain(); echo "<hr/>"; $youkaiObj->showHighLight();
ここでファイル表示の関数に関して次の変更を行いたい。
- showPlain()の使用禁止
- showHighLight()の継続使用
しかし、動作実績豊富なWatchYoukai.class.phpに関して変更を行いたくない。
そんな時にAdapterパターンが活躍する。WatchYoukai.class.phpに手を入れずに、WatchYoukaiクラスのAPIを継承したクラスを別に作成するパターンです。
DisplayYoukai.class.php
<?php interface DisplayYoukai { /* * 指定したファイルをハイライト表示する */ public function display(); }
継承を使ったやり方
DisplayYoukaiImpl.class.php
<?php require_once 'DisplayYoukai.class.php'; require_once 'WatchYoukai.class.php'; class DisplayYoukaiImpl extends WatchYoukai implements DisplayYoukai { public function __construct($filename_) { parent::__construct($filename_); } public function display() { parent::showHighLight($filename_); } }
adapter_client.php
<?php require_once 'DisplayYoukaiImpl.class.php'; try{ $youkaiObj = new DisplayYoukaiImpl('./WatchYoukai.class.php'); }catch(Excetion $e){ die($e->getMessage()); } $youkaiObj->display();
または移譲を使ったやり方として、
DisplayYoukaiImpl_transfer.class.phpのようにもかけます。
<?php require_once 'DisplayYoukai.class.php'; require_once 'WatchYoukai.class.php'; class DisplayYoukaiImpl extends WatchYoukai implements DisplayYoukai { private $show_file; public function __construct($filename_) { $this->show_file = new Showfile($filename_); } public function display() { $this->show_file->showHighLight($filename_); } }
@see http://d.hatena.ne.jp/shimooka/20141212/1418364494