在应用程序中,你也许会使用一个文档的代码库,然而,我们常常要添加新的功能,这些功能要求使用不同的方式使用现有的对象。可能新功能只是需要一个不同的名字,也可能是新功能需要与原有的对象稍有不同的行为。
针对上述问题,采用适配器模式是个很好的解决方案。使用适配器模式创建另一个对象,这个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教程有兴趣的朋友有所帮助。