第十六讲:适配器模式
笔记本电脑有一个电源适配器,笔记本的工作电压是18V或者是20V.家常用电是220V.
应用场景:客户端需要调用一个组件,但是这个组件可能还不大成熟.以后随时可能替换成另外一个组件.客户端通过适配器(Adapter)调用外部组件(Current)的方法,而且客户端直接调用外部组件(Current)的话,替换外部组件的时候就需要修改客户端的代码.我是在调用适配器Adapter,如果Current被替换了,我只要改好适配器就可以了.这个适配器可以调用另外一个外部组件的方法就行了.无需在主体的代码/客户端的代码进行修改.降低了客户端的代码的修改面.
public class Adapter extends Current{ public void use18V(){ System.out.println("使用适配器"); this.user220V(); } }
上面那种是通过继承实现的,委让是通过组合来实现,它持有它的一个引用,一种聚合关系.Adapter适配器持有了被适配的类Adaptee的一个引用.因为持有了引用,所以可以很好地在里面进行修改,很好地调用.
public class Adapter2 { private Current curerent;//持有被适配的引用. public Adapter2(Current curerent) { super(); this.curerent = curerent; } public void user18V(){ System.out.println("使用适配器"); this.curerent.user220V(); } }
public class Current { public void user220V(){ System.out.println("使用220V电流"); } }
//客户端直接使用220V电流. //加一个适配器 public class MainClass { public static void main(String[] args) { /* Current current = new Current(); current.user220V();*/ /* Adapter adapter = new Adapter(); adapter.use18V();*/ Adapter2 adapter = new Adapter2(new Current()); adapter.user18V();//requiredMethod是user18V() //oldMethod()是user220V() } }
两种适配器模式,一种是继承,一种是委让.根据自己需求选择. 委让用的比较多,持有的是它的引用,更加灵活.
大话设计模式的适配器模式的例子:姚明金NBA不会英语带翻译.翻译就是适配器.大话设计模式用的是C#语言.但是思想是一样的.客户端MainClass不能调用user220V(),只能调用user18V().客户端调用的外部组件Currrent,还不太成熟,你不能直接调用它.是不是重新建一个电厂或者是重新接一根线这根线接的是18V的电流,然后直接接上就可以用?暂时使用,可以直接使用但是直接使用替换起来会进行大面积的修改,把外部组件修改掉.如果直接调用的话修改了外部组件的一个方法(比如add()),客户端代码会进行大面积的修改.
如果使用了Adapter的add()方法,适配器里面的add()方法也调用外部组件的add方法.如果修改了外部组件的话,如果是继承的话就把继承的父类和继承关系改掉,如果是聚合的话就把持有的引用改掉.
系统的设计应该是放在前期,前期已经把这些设计都规范好了.适配器模式的存在表示前期的设计是不规范的,不规范才需要适配器模式.没有一个程序是完美的,像XP系统经常需要安装补丁更新.当你的系统需要做一个新的功能的时候,以前设计的时候可能没考虑到这个功能,就需要考虑到程序的扩展性.一个新的东西的产生可能会带来改动.这是无法避免的.为什么需要适配器模式?就需要一个模式能够减少改动.最大限度地降低修改面.因为外部组件也是暂时使用的,临时性的,随时替换的.需要替换的话你就需要有一个规范化了.比如说都希望使用这个user18V()这个方法.有些电流(外部组件)它没有这个方法,它只能接受220V.那么我就把这个适配器拿出来,适配器它可以接受18V,并且它里面的核心就是调用220V.那么客户端就可以用了.客户端用适配器和你打交道,不和外部组件直接打交道.
适配器设计模式把翻译当成了适配器,