适配器模式的定义:将某个对象的接口转换为客户希望的另外一个接口。(四人组的设计模式一书)
通俗的说就是:我需要某个对象,但是这个对象是没法直接获得的。可是系统中存在的类似的东西。
这个时候我们就可以用继承或者是实现接口的方式创建一个新的类,创建这个类的实例满足我们的需求。
这样就可以避免去修改系统中的代码。符合面向对象5原则中的开发封闭原则
信号-显卡-显示器
/** 二进制信号 signal **/ class Signal { public function processing() { echo "base signal processing"; } }
显示器需要接受信号,可是它没办法处理二进制信号
怎么办?
两种解决办法:
1 修改signal类 添加新的方法,
2 创建一个adapter类让它出来二进制信号。
方法一
class Signal1 { public function processing() { echo " base signal processing "; } public function processingBinary() { $this->processing(); echo " binary signal processing "; } }
/** 显示器 **/ class Monitor1 { protected $signal = null; public function __construct($signal) { $this->signal = $signal; } /** 显示图像 **/ public function show() { if(empty( $this->signal) || !( $this->signal instanceof Signal1) ){ echo " no signal "; } else{ $this->signal->processingBinary(); echo " show singal on the screen "; } } } $monitor = new Monitor1(new Signal1()); $monitor->show();
方法二
class SignalAdapter extends Signal { public function processing() { parent::processing(); echo "base signal processing"; } } /** 显示器 **/ class Monitor { protected $signal = null; public function __construct($signal) { $this->signal = $signal; } /** 显示图像 **/ public function show() { if(empty($this->signal) || !($this->signal instanceof Signal) ){ echo " no signal"; } else{ $this->signal->processing(); echo " show singal on the screen"; } } } $monitor = new Monitor(new SignalAdapter()); $monitor->show();
方法一缺点:
旧的方法可能正在被使用,比较好的办法是添加新的方法,违背了面向设计的原则,会造成重复。
不够灵活,不利于扩展,假如当我们要添加新信号处理的时候又要去修改signal类
优点:
简单方便
方法二缺点:
需要建造新的类,增加代码的复杂度,繁琐
优点:
灵活,利于扩展