码迷,mamicode.com
首页 > 其他好文 > 详细

headFirst学习笔记之七:适配器模式与外观模式(4.30)

时间:2015-04-30 17:59:59      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!