需求:只需要將日誌記錄到文件中。(日誌系統第一版)
/**
* 日誌系統第一版
* @author ranping
*/
class LogModel {
private $logId;
private $operateUser;
private $operateTime;
private $logContent;
public function getLogId() {
return $this->logId;
}
public function getOperateUser() {
return $this->operateUser;
}
public function getOperateTime() {
return $this->operateTime;
}
public function getLogContent() {
return $this->logContent;
}
public function setLogId($logId) {
$this->logId = $logId;
}
public function setOperateUser($operateUser) {
$this->operateUser = $operateUser;
}
public function setOperateTime($operateTime) {
$this->operateTime = $operateTime;
}
public function setLogContent($logContent) {
$this->logContent = $logContent;
}
public function toString(){
return "";
}
}
interface LogFileOperateApi {
abstract public function readLogFile();
abstract public function writeLogFile();
}
class LogFileOperate implements LogFileOperateApi {
public function __construct() {
}
public function readLogFile() {
}
public function writeLogFile() {
}
}
class Client {
public static function main() {
$logModel = new LogModel();
$list = array();
$list[] = $logModel;
$api = new LogFileOperate();
$api->writeLogFile($list);
$readLog = $api->readLogFile();
}
}
增加需求:
增加數據庫的方式記錄日誌。並且需要讓之前的版本能正常運行。
如果僅僅是採用文件的方式來記錄日誌文件,沒有什麼問題。看上也很容易對吧,但使用一段時間之後,開始考慮升級系統,決定採用數據庫來管理日誌。
interface LogDbOperateApi {
abstract public function createLog();
abstract public function updateLog();
abstract public function removeLog();
abstract public function getLog();
}
class LogDbOperate implements LogDbOperateApi {
public function createLog() {}
public function getLog() {}
public function removeLog() {}
public function updateLog() {}
}
此時此該,遇到的問題:
1. 新系統有的第二版日誌,舊系統的使用的是第一版日誌。而新系統與舊系統的接口不一樣所以無法,所以導致新系統無法以同樣的方式來來直接使用第一版的日誌行爲。
2. 最先想到的解決方法是,重寫第一版的寫到文件中的實現方式。但是,其它功能可能依賴之前的實現,直接更改會導致故障。如果根本看不到源代碼呢?
解決方案:
適配器模式
適配器模式的代碼:
interface Target {
public function request();
}
class Adaptee {
public function specificRequest() {
//todo
}
}
class Adapter implements Target {
private $adaptee;
public function __construct($adaptee) {
$this->adaptee = $adaptee;
}
public function request() {
$this->adaptee->specificRequest();
}
}
class Client {
public static function main() {
$adaptee = new Adaptee();
$taget = new Adapter($adaptee);
$taget->request();
}
}
用適配器模式進行實現日誌系統: (第二版)
class Adapter implements LogDbOperateApi {
private $adaptee = null;
public function __construct($adaptee) {
$this->adaptee = $adaptee;
}
public function createLog() {
//用$this->adaptee去實現功能
}
public function getLog() {
//用$this->adaptee去實現功能
}
public function removeLog() {
//用$this->adaptee去實現功能
}
public function updateLog() {
//用$this->adaptee去實現功能
}
}
class Client {
public static function main() {
$logModel = new LogModel();
$list = array();
$list[] = $logModel;
$logFileApi = new LogFileOperate();
$logDbApi = new Adapter($logFileApi);
//todo $logDbApi 實現 了用 LogDbOperateApi接口去操作。
}
}
適配器模式講解:
功能:進行轉換匹配,目的是複用已有功能,不是用業實現新接口。
把不兼容的接口轉換爲客戶期望的樣式。