適配器模式/代理模式/裝飾器模式/工廠模式
阿新 • • 發佈:2017-10-29
取數 取數據 cat remote struct catch span 擁有 rto
適配器模式
要對原有的類的功能進行擴展,但又不希望改變原有類的功能,來適應新的需求,這時候可以從原有類繼承,實現一個適配器,這不會改變原有類的功能,又可以添加新的功能.
1.類適配器
class A { public function methodA() { .............. } } class Adapter extends A { private $objectA; public function methodB() { echo ‘Append data‘; } } 調用: $a = new Adapter(); $a->methodA(); $a->methodB(); Adapter既擴展了A類,又沒有改變A類的功能.為了體現裏氏原則,一般繼承類不覆蓋父類的方法(構造方法除外).再者覆蓋了,還不如直接改原來類,適配器也就沒意義了.這個模式看起來特別像是普通的繼承,
只不過是子類實現了父類中不存在的一些方法.
2.對象適配器:
class A { public function methodA() { .............. } } // 適配器 class Adapter { private $objectA; public function __construct(A $a) { $this->$objectA = $a; } public function methodA() { $this->objectA->methodA(); } public function methodB() { // .... } } //調用 $a = new A(); $adapter = new Adapter($a); $adapter->methodA(); $adapter->methodB(); 對象適配器不使用繼承,在構造函數中實例化另一個類. 類適配器和對象適配器的調用方式也有所不同,是否需要構造源類,是兩者的區別.
代理模式
代理設計模式構建了透明置於兩個對象之內的一個對象,從而能夠截取或代理這兩個對象間的通信或訪問.
舉個例子,之前我們有個CD類,從127.0.0.1上的mysql數據庫獲取數據;後面因為性能擴展,我們需要該CD類從192.168.2.10上獲取數據.使用代理模式來實現: class CD { protected $link = null; protected static $instance = null; protected function __construct() { $this->connect(); } public static function getInstance() { if (is_null(self::$instance)) { self::$instance = new static(); //此處註意和new self的區別 } return self::$instance; } public function getAll() { $res = $this->link->query("SELECT * FROM cd"); $data = array(); foreach ($res as $row) { $data[] = $row; } return $data; } public function connect() { if (is_null($this->link)) { $this->link = new PDO(‘mysql:host=127.0.0.1;dbname=test‘, ‘root‘, ‘root‘); } } public function close() { $this->link = null; } } // 代理類 class RemoteCD extends CD { public function connect() { if (is_null($this->link)) { try { $this->link = new PDO(‘mysql:host=192.168.2.10;dbname=test‘, ‘root‘, ‘root‘); } catch (Exception $e) { die($e->getMessage()); } } } } $cd = RemoteCD::getInstance(); var_dump($cd->getAll());
裝飾器模式
代理設計模式構建了透明置於兩個對象之內的一個對象,從而能夠截取或代理這兩個對象間的通信或訪問.
class A { public $nameList = array(); public function methodA() { $this->nameList[] = ‘peter‘; } } // 裝飾器 class Decorator { private $objectA; public function __construct(A $a) { $this->objectA = $a; } public function toUpper() { // 改變了原有對象的內容 foreach($this->objectA->nameList as &$val) { $val = strtoupper($val); } } } // 調用 $a = new A(); $decorator = new Decorator($a); $decorator->toUpper(); var_dump($a->nameList);
ps:代碼體現了已有對象的部分內容或功能性發生改變,但是不需要改變原始對象的結構.如果不改變已有對象,可以用適配器.裝飾器,必須要裝飾一個對象,裝飾這個意思就是改變已有對象的內容或功能.
工廠模式
提供獲取某個對象的新實例的一個接口,同時使調用代碼避免確定實際實例化基類的步驟.
class A { public function song($songList) { foreach($songList as $val) { echo $val . ‘.mp3‘; } } } class B { public function song($songList) { foreach($songList as $val) { echo $val . ‘.wav‘; } } } class Factory { public static function create($type, $list) { return new $type($list); } } $songList = Factory::create(‘A‘, array(‘a.mp3‘, ‘b.mp3‘)); 特點: 工廠模式為擁有相同方法的類提供一個統一的訪問實例的接口. 工廠自身並不負責主要數據的處理,全部交由工廠中實例化的類來完成.
適配器模式/代理模式/裝飾器模式/工廠模式