需求:只需要将日志记录到文件中。(日志系统第一版)
/** * 日志系统第一版 * @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接口去操作。 } }
适配器模式讲解:
功能:进行转换匹配,目的是复用已有功能,不是用业实现新接口。
把不兼容的接口转换为客户期望的样式。