设计模式之适配器模式 adapter
2012-08-16 19:58
459 查看
最近看了《PHP设计模式》,觉得对自己帮助很大,所有想把该书提到的一些主要设计模式拿出来和大家分享,其中加入自己的理解,希望大家支持。
本系列文章着重介绍设计模式的思想,为了便于读者们的理解,一个设计模式的介绍开始到最后分 三步走:
问题与解决方案
从最浅显的需求入手讲解,更好的理解思想以及什么时候使用该设计模式。
UML
一目了然的看清晰框架(我也是第一次画图,不合理的地方,欢迎指正。)
代码示例
对于程序员来说,看代码可能比看枯燥的文字更加理解得快,所有我会用PHP语言写一个完整的简单的实例。
好了,进入正题,这一次我主要写的是 -- 适配器模式
首先,我说说我理解的需要使用适配器模式的假设:
插线板相信大家都用过,我觉得,它就是我们生活中最好的适配器写照。当然我是说的它的转换插口功能。比如家里墙壁上边的插座都是二孔插座,现在买回一个三孔电器,必须得要三孔插座才行。
遇到此情况,马上想到三种解决方法:
1.换墙壁上的插座
2.换买回来的电器三孔插口
3.使用插件板,把二孔插座转换成三孔插座
想想,哪种解决方案最优,最完美。要是你,你会怎么选择?其实在程序中,也有这样子的抉择。
一,问题与解决方案
在项目最初的代码库中,名为errorObject的对象能够处理所有的错误消息和代码。最初的编程人员并不认为自己的代码会产生任何错误,因此他们设计系统将errorObject对象的错误消息直接输出至控制台。
下面示例会生成一个“404:Not Found”错误。我们假定错误消息的内容和代码可能变化,但是以文本的方式以及记录格式始终一样。
在这个场景中,项目中加入了新的网络管理员。建议的最佳做法是安装用于监控软件的网络日志。网络管理员选择的软件包要求将错误日志记录至一个多列的CSV文件。具体的CSV格式要求第一列是错误值代码,第二天应当是错误文本。
选择的新软件包也可使用errorObject类,遗憾的是,版本不同。新的软件包logToCVS类如下:
针对这个问题,我们可以采用下面两种解决方案:
1.更改现有代码库的errorObject类。
2.创建一个Adapter(适配器)对象。
考虑到保持errorObject原来标准型的需求,因此创建一个Adapter对象是最佳的解决方案。
新创建的适配器对象中必须存在现有的errorObject的功能性。此外,getErrorNum()和getErrorText()公共方法也必须有。在传统的errorObject类中,getError()方法用户获取错误消息。Adpater(适配器)对象应当利用该方法从父类中获取错误消息,然后再转化输出供给二个新公共方法使用。
最后,为了实现这个适配器,必须通过使用该适配器替代原来的errorObject来更新代码。这样,logToCSV类就能够接受被适配器的类(而不是原来的errorObject类),从而使原来的代码能够像logToCSV类期望那样运行。
二,UML
View Code
适配器模式大致思想就是这样,代码很简单,也很容易理解。不懂的童鞋可以多看几遍代码,可能更容易理解。下一篇写 -- 建造者模式。
本系列文章着重介绍设计模式的思想,为了便于读者们的理解,一个设计模式的介绍开始到最后分 三步走:
问题与解决方案
从最浅显的需求入手讲解,更好的理解思想以及什么时候使用该设计模式。
UML
一目了然的看清晰框架(我也是第一次画图,不合理的地方,欢迎指正。)
代码示例
对于程序员来说,看代码可能比看枯燥的文字更加理解得快,所有我会用PHP语言写一个完整的简单的实例。
好了,进入正题,这一次我主要写的是 -- 适配器模式
首先,我说说我理解的需要使用适配器模式的假设:
插线板相信大家都用过,我觉得,它就是我们生活中最好的适配器写照。当然我是说的它的转换插口功能。比如家里墙壁上边的插座都是二孔插座,现在买回一个三孔电器,必须得要三孔插座才行。
遇到此情况,马上想到三种解决方法:
1.换墙壁上的插座
2.换买回来的电器三孔插口
3.使用插件板,把二孔插座转换成三孔插座
想想,哪种解决方案最优,最完美。要是你,你会怎么选择?其实在程序中,也有这样子的抉择。
一,问题与解决方案
在项目最初的代码库中,名为errorObject的对象能够处理所有的错误消息和代码。最初的编程人员并不认为自己的代码会产生任何错误,因此他们设计系统将errorObject对象的错误消息直接输出至控制台。
下面示例会生成一个“404:Not Found”错误。我们假定错误消息的内容和代码可能变化,但是以文本的方式以及记录格式始终一样。
//传统错误处理类 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(){ $erroMsg = $this->_errorObject->getError(); echo $erroMsg; file_put_contents('error.log', $erroMsg); } } //创建一个错误对象 $error = new errorObject('404: Not Found'); //控制台写入日志文件 $log = new logToConsole($error); $log->write();
在这个场景中,项目中加入了新的网络管理员。建议的最佳做法是安装用于监控软件的网络日志。网络管理员选择的软件包要求将错误日志记录至一个多列的CSV文件。具体的CSV格式要求第一列是错误值代码,第二天应当是错误文本。
选择的新软件包也可使用errorObject类,遗憾的是,版本不同。新的软件包logToCVS类如下:
//检测日志软件要使用 csv格式的错误日志 错误号:解释内容 class logToCSV{ const CSV_FILE_PATH = 'error.csv'; public function __construct($errorObject){ $this->_errorObject = $errorObject; } //csv 格式 错误号:解释内容 public function write(){ $erroMsg = $this->_errorObject->getErrorNumber(); $erroMsg .= ','; $erroMsg .= $this->_errorObject->getErrorText(); echo $erroMsg; file_put_contents(self::CSV_FILE_PATH, $erroMsg); } }
针对这个问题,我们可以采用下面两种解决方案:
1.更改现有代码库的errorObject类。
2.创建一个Adapter(适配器)对象。
考虑到保持errorObject原来标准型的需求,因此创建一个Adapter对象是最佳的解决方案。
新创建的适配器对象中必须存在现有的errorObject的功能性。此外,getErrorNum()和getErrorText()公共方法也必须有。在传统的errorObject类中,getError()方法用户获取错误消息。Adpater(适配器)对象应当利用该方法从父类中获取错误消息,然后再转化输出供给二个新公共方法使用。
//最好的解决方法是,创建一个 csv 的适配器类来处理 class logToCSVAdapter extends errorObject{ private $_errorNumber; private $_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; } }
最后,为了实现这个适配器,必须通过使用该适配器替代原来的errorObject来更新代码。这样,logToCSV类就能够接受被适配器的类(而不是原来的errorObject类),从而使原来的代码能够像logToCSV类期望那样运行。
//适配器调用代码(实际上就是用子类替代父类,在子类中一系列处理方法) $errorAdapter = new logToCSVAdapter('404:Not Found'); $log = new logToCSV($errorAdapter); $log->write();
二,UML
View Code
<?php //适配器模式 //例1,错误日志处理 //传统错误处理类 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(){ $erroMsg = $this->_errorObject->getError(); echo $erroMsg; file_put_contents('error.log', $erroMsg); } } //检测日志软件要使用 csv格式的错误日志 错误号:解释内容 class logToCSV{ const CSV_FILE_PATH = 'error.csv'; public function __construct($errorObject){ $this->_errorObject = $errorObject; } //csv 格式 错误号:解释内容 public function write(){ $erroMsg = $this->_errorObject->getErrorNumber(); $erroMsg .= ','; $erroMsg .= $this->_errorObject->getErrorText(); echo $erroMsg; file_put_contents(self::CSV_FILE_PATH, $erroMsg); } } //最好的解决方法是,创建一个 csv 的适配器类来处理 class logToCSVAdapter extends errorObject{ private $_errorNumber; private $_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 errorObject('404: Not Found'); //控制台写入日志文件 $log = new logToConsole($error); $log->write(); //适配器调用代码(实际上就是用子类替代父类,在子类中一系列处理方法) $errorAdapter = new logToCSVAdapter('404:Not Found'); $log = new logToCSV($errorAdapter); $log->write();
适配器模式大致思想就是这样,代码很简单,也很容易理解。不懂的童鞋可以多看几遍代码,可能更容易理解。下一篇写 -- 建造者模式。
相关文章推荐
- Java设计模式之适配器模式(Adapter)
- 设计模式–Adapter模式(适配器模式)
- java设计模式6--适配器模式(Adapter )
- 【设计模式】—— 适配器模式Adapter
- 设计模式-适配器模式(Adapter)
- 设计模式之四:适配器模式(Adapter Pattern)
- 设计模式学习----Adapter(适配器模式)
- 设计模式--学习笔记--适配器模式Adapter--基础篇
- 设计模式(五)适配器模式Adapter(结构型)
- 设计模式-适配器模式(Adapter Pattern)
- 设计模式之适配器模式(Adapter Pattern)C++实现
- 设计模式之适配器模式(Adapter)
- 设计模式——适配器模式【Adapter Pattern】
- 设计模式——适配器模式(Adapter)
- 23种设计模式之-----适配器模式(Adapter Pattern)
- 深入浅出设计模式-007:适配器模式(Adapter Pattern)
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
- 设计模式之适配器模式Adapter
- 设计模式之适配器模式(Adapter)
- [工作中的设计模式]适配器模式adapter