标签:
1.什么是适配器:
现实生活:如果要在欧洲使用美国制造的笔记本,可能需要一个交流电的适配器。有些交流电适配器只是改变插座的形状,有些会改变电流符合装置的需求。
OO适配器:将一个接口转换成另一个接口,以符合客户的期望。
例子:如果它走起来像鸭子,叫起来像鸭子,那么它必定可能是一只鸭子包装了鸭子适配器的火鸡。
1 public interface Duck{ 2 public void fly(); 3 public void quack(); 4 } 5 6 public class MallardDuck implements Duck{ 7 public void quack(){ 8 System.out.println("Quack"); 9 } 10 11 public void fly(){ 12 System.out.println("I am flying"); 13 } 14 }
1 public interface Turkey{ 2 public void gobble(); 3 public void fly(); 4 } 5 6 public class WildTurkey implements Turkey{ 7 public void gobble(){ 8 System.out.println("Gobble"); 9 } 10 11 public void fly(){ 12 System.out.println("I am flying a short distance"); 13 } 14 }
1 public class TurkeyAdapter implements Duck{ 2 Turkey turkey; 3 public TurkeyAdapter(Turkey turkey){ 4 this.turkey = turkey; 5 } 6 7 public void quack(){ 8 turkey.gobble(); 9 } 10 11 public void fly(){ 12 for(int i=0;i<5;i++){ 13 turkey.fly(); 14 } 15 } 16 }
1 public class DuckTestDrive(){ 2 public void main(String[] args){ 3 WildTurkey turkey = new WildTurkey(); 4 Duck turkeyAdapter = new TurkeyAdapter(turkey); 5 6 testDuck(turkeyAdapter); 7 } 8 9 static void testDuck(Duck duck){ 10 duck.fly(); 11 duck.quack(); 12 } 13 }
2.两种适配器:对象适配器(上面那种)和类适配器。类适配器需要多重继承才能实现,所以在java中是用不了的,但是再可以用多重继承的编程语言中,可能会有这种需求。它们两个之间的差别就是:对象适配器中,Adapter是implements了目标接口(Duck),然后通过组合,委托了Adatptee(Turkey)去完成。在类适配器中,Adapter继承自目标接口Duck,并且继承Adaptee(Turkey)。
3.真实世界的适配器:
早期的集合(collection)类型都实现了一个名为elements()的方法,他会返回一个Enumeration(枚举),这个接口可以遍历此集合内的每个元素。更新后的集合类型,开始使用Iterator(迭代器),同样可以遍历,增加了删除能力。
任务:面对遗留代码,常常暴露出枚举器接口,但是我们在新代码中只想用迭代器接口,所以要将旧世界的枚举器,适配到新世界的迭代器。
1 interface Enumeration{ 2 hasMoreElements(); 3 nextElements(); 4 } 5 6 interface Iterator{ 7 hasNext(); 8 next(); 9 remove(); 10 }
anna想:用对象适配器的时候,Adapter收到Target的方法调用时,会委托给Adaptee,也就是说,Target的方法要用Adaptee的方法来实现,有个对应关系。很明显:hasMoreElements对应hasNext,nextElements对应next,但是要实现remove时,怎么办呢?
回答:枚举不支持删除,因为是只读接口,所以适配器无法实现"实际"的remove()方法,最多只能抛出一个运行时异常。
1 public class EnumerationIterator implements Iterator{ 2 ... 3 public void remove(){ 4 throw new UnsupportedOperationException(); 5 } 6 }
4.外观模式(Facade-Pattern):
也要改变接口,但是接口的目的不是为了兼容,而是为了简化接口。将一个或者数个类的复杂一切都隐藏在背后,只显露出一个干净美好的外观。
真实世界的例子:我刚刚组装了一套家庭影院的杀手级系统,内含DVD播放器,投影机,自动屏幕,环绕立体声,还有爆米花机。好的,我准备看电影了,我选了gone girl,听说不错。然后我发现我要做的事情有:心好累。看完还有关掉,如果我升级了系统,还得重新学习操作。
1 popper.on(); 2 popper.pop(); 3 lights.dim(10); 4 screen.down(); 5 projector.on(); 6 projector.setInput(dvd); 7 projector.wideScreenMode(); 8 amp.on(); 9 amp.setDvd(dvd); 10 amp.setSurroundSound(); 11 amp.setVolueme(5); 12 dvd.on(); 13 dvd.play("gone girl");
解决办法:新建一个类,只对外暴露一些简单的方法,然后调用子系统来实现具体操作。(hey,别担心,还是可以使用原来的复杂接口的,只是增加一个简单接口。它并没有封装子系统的类!!)
1 class HomeTheaterFacade(){ 2 watchMovie(){} 3 endMovie(){} 4 listenToCD(){} 5 endCD(){} 6 listenToRadio(){} 7 endRadio(){} 8 }
headFirst学习笔记之七:适配器模式与外观模式(4.30)
标签:
原文地址:http://www.cnblogs.com/liyuhui21310122/p/4469356.html