在應用程式中,你也許會使用一個文檔的程式碼程式庫,然而,我們常常要添加新的功能,這些功能要求使用不同的方式使用現有的
對象。可能新功能只是需要一個不同的名字,也可能是新功能需要與原有的
對象稍有不同的行為。
針對上述問題,採用適配器模式是個很好的解決方案。使用適配器模式建立另一個對象,這個Adapter對象充當了原始應用與新功能之間的中介。適配器設計模式只是將某個對象的介面適配為另一個對象所期望的介面。
程式碼範例:
class errorObject{private $_error;public function __construct($error){$this->_error = $error;}public function getError(){return $this->_error;}}class logToConsole{private $_errorObject;public function __construct($errorObject){$this->_errorObject = $errorObject;}public function write(){fwrite(STDERR, $this->_errorObject->getError());}}$error = new errorObject("404:Not Found");$log = new logToConsole($error);$log->write();
假如有一天需求改變了,要求將錯誤記錄到一個CSV檔案中,CSV的格式要求第一列是數值錯誤碼,第二列是錯誤文本。新需求已經給出了實現日誌記錄的代碼,問題是這些代碼是根據errorObject的另一個版本編寫的,該版本與當前使用的版本不同。新的errorObject類具有另外兩個名為getErrorNumber()和getErrorText()的方法,logToCSV類會使用到這兩個方法:
class logToCSV{const CSV_LOCATION = "log.csv";private $_errorObject;public function __construct($errorObject){$this->_errorObject = $errorObject;}public function write(){$line = $this->_errorObject->getErrorNumber();$line .= ',';$line .= $this->_errorObject->getErrorText();$line .= '\n';file_put_contents(self::CSV_LOCATION, $line, FILE_APPEND);}}
針對這個問題,我們可以採用下面兩種解決方案:
● 建立現有程式碼程式庫的errorObject類;
● 建立一個Adapter類;
考慮到保持這些公用介面標準性的需求,因此建立一個Adapter對象是最佳的解決方案。
新建立的適配器對象中必須存在現有errorObject的功能性,而且,getErrorNumber()和getErrorText()方法必須有效。
class logToCSVAdapter extends errorObject{private $_errorNumber, $_errorText;public function __construct($error){parent::__construct($error);$parts = explode(':', $this->getError());$this->_errorNumber = $parts[0];$this->_errorText = $parts[1];}public function getErrorNumber(){return $this->_errorNumber;}public function getErrorText(){return $this->_errorText;}}$error = new logToCSVAdapter("404:Not Found");$log = new logToCSV($error);$log->write();
在需要轉化一個
對象的介面用於另一個
對象時,實現Adapter
對象不僅是最佳做法,而且也能減少很多麻煩。
適配器模式一般使用情境:
● 資料庫驅動(可查看各架構的驅動部分源碼)
● webservices(在多個不同的webservices中,使用適配器)
以上就介紹了PHP設計模式——適配器模式Adapter,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。