现在的位置: 首页 > 综合 > 正文

PHP设计模式——适配器模式(研磨设计模式学习笔记)

2014年02月25日 ⁄ 综合 ⁄ 共 2665字 ⁄ 字号 评论关闭
需求:只需要将日志记录到文件中。(日志系统第一版
/**
 * 日志系统第一版
 * @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接口去操作。
	}
}

适配器模式讲解:
       功能:进行转换匹配,目的是复用已有功能,不是用业实现新接口。
                  把不兼容的接口转换为客户期望的样式。

抱歉!评论已关闭.