我们先来看个现实的例子,比如说我们买的新家电插头是3个头的,还是圆形头,而家里插座是2头的,如下图(用windows画笔画的,画画毫无天赋,图案比较恐怖,哈哈),这该怎么办呢.
明显型号不匹配,那么我提供2个方案
1:去换一台新家电,直到有匹配的2方头插头.
2:砸掉家里墙壁上的插座,换个3圆头的插座.
大家看到这个肯定说我秀逗了,买个转接头,或则多功能转接插座,接上去就好了
嗯,不错,这转接头(转接插座)就是起的适配器的角色,把本能不匹配的接口,通过适配器正常工作,而双方都不需要做任何改动.
so,大家都知道这点,再看适配器模式就再简单不过了,把本来不匹配的2个类,接口,通过适配器让他们正常工作.uml图如下
这里Client需要的接口是ITarget,而实际上我们要调用的接口是IAdaptee,为了实现这个目标,我们就实现了一个类adapter实现了ITarget接口,并把IAdaptee的实例作为其中一个组件,当响应client请求的时候,Adapter就会去call Adaptee组件
上面给出的是object adapter模式,还有一种class adapter模式,如下图:
adapter直接继承adaptee,而不是作为组件,这个本身已经违反了面向对象的 使用组件,而不是继承 的这项基本原则.但我们使用设计模式的时候并不需要那么死板,如果有很大好处的时候,还是要用的.
实例分析
这个模式应用很广,但本身却很简洁.很容易理解,看上面uml图,大家都已经差不多掌握了.这里还是给出个实例来分析实现
我们现在有个系统,旧的系统调用数据库,获得DataSet,一直用的是数据接口的GetDataSet,如下
而新的数据接口有变化,用的是ExecuteDataSet,
这真的是头疼的事,2边都不好改,那么我们adapter就要上场了,
采用object adapter模式,代码如下:
ok,那么客户端调用这个adapter的时候,完全不知道里面调用的方法已经变了,还是用以前的方式一样调用.调用者和实际被调用者呈现松耦合关系.代码类似下面代码:
当然,我们也可以采用class adapter模式来写adapter类,代码如下(不推荐):
代码简洁了很多,但付出的代价是继承了Adaptee类,保持了紧耦合.
思考
object adapter跟decorater模式还是有点像.都是包装了一个组件.实际调用都会直接去调用这包装好的组件的方法,不过decorater在装饰过程中,本身接口没变.object adapter实现了一个接口对另一个接口的转换.
下一篇:《Head First Design Patterns》笔记八:外观模式(Facade Pattern)
上一篇:《Head First Design Patterns》笔记六:命令模式(Command Pattern)