适配器模式和外观模式

      适配器模式提供了将一种对象转换成另外一种对象的能力,利用它能够实现两个不兼容接口的协调工做。外观模式是封装对象内的复杂逻辑,对外提供一个简化的接口。html

1. 适配器模式

      生活中最多见的适配器的使用场景就是各类转换线和转换插头,例如投影仪到电脑之间的转换线,港版iPhone和国内插座之间的转换插头等。下面就以iPhone和插座之间的转换插头为例来看看适配器模式的用法。设计模式

      港版iPhone使用的英式插头,如左图所示,这种插头无法直接插在国内的标准插座上,要使用相似右图的转换器才行,那么如今须要作的就是找到一个转换器(适配器),将英式插头转换成符合国内标准的插头,也就是将EnglishPlug转换成ChinesePlug。(注:下面两个图片来源:https://zhidao.baidu.com/question/1365859698524477699.htmlide

                                      

 

 

 

       先看一下插头的定义:测试

1 public interface EnglishPlug{
2     void charge();  // 英式插头能够插到插座上充电  
3 }
4 
5 public interface ChinesePlug{
6     void charge();  // 中式插头也能够插到插座上充电  
7 }

      接下来是英式iPhone插头和中式iPhone插头:this

 1  public class EnglishiPhonePlug implements EnglishPlug{
 2      @Override
 3      public void charge(){
 4          System.out.println("英式插头在充电");
 5      }
 6  }
 7  
 8  public class ChineseiPhonePlug implements ChinesePlug{
 9      @Override
10     public void charge(){
11         System.out.println("中式插头在充电");
12     }
13 }

      因为两个插头都已经作好了,回炉重造确定是不可能了,只能增长一个转换器PlugConverter,将EnglishPlug假装成ChinesePlug,好让英式插头能在中式插座上充电。要假装成ChinesePlug,就须要让PlugConverter实现ChinesePlug接口,在转换器中组合EnglishPlug来完成转换工做,代码以下:spa

 1 publich class IPhonePlugConverter implements ChinesePlug{
 2     private EnglishPlug englishPlug;
 3     
 4     public IPhonePlugConverter(EnglishPlug englishPlug){
 5         this.englishPlug = englishPlug;
 6     }
 7 
 8     @Override
 9     public void charge(){
10         englishPlug.charge();
11     }
12 }

      如今须要写一个测试类来看看这个转换成到底能不能用:设计

1 public static void main(String[] args){
2     ChinesePlug chinesePlug = new IPhonePlugConverter(new EnglishiPhonePlug());
3     chinesePlug.charge();  //输出:英式插头在充电
4 }

      能够看到,咱们成功的用EnglishPlug“冒充”了ChinesePlug,实现了转换器的功能。固然,上面介绍的只是讲一个接口转换成另外一个接口,实际上能够将一个接口转换为多个其余接口。code

2. 外观模式

      外观模式提供了简化接口的能力,将内部复杂的实现封装起来,开放给外部一个简单的接口,从而下降使用的复杂性。htm

以洗衣机为例,洗衣机有半自动和全自动两种,半自动洗衣机须要咱们本身先注水,而后洗涤,放水,最后脱水,这几部须要咱们手动一步一步完成,虽然能够作到精细化控制(例如能够自由选择注水多少,脱水几分钟),可是用起来难免有些麻烦,而全自动洗衣机只须要按下启动键就OK了,简单了许多。对象

      下面是半自动洗衣机的定义:

 1 public class SemiautoWashingMachine{
 2     public void addWater(){
 3         System.out.println("手动注水");
 4     }
 5 
 6     public void washing(){
 7         System.out.println("开始洗衣服");
 8     }
 9 
10     public void drainage(){
11         System.out.println("手动排水");
12     }
13 
14     public void dehydration(){
15         System.out.println("手动脱水");
16     }
17 }

      用户使用半自动洗衣机,须要一步一步分别调用addWater(),washing(), drainage(), dehydration()这些接口。

      全自动洗衣机定义以下:

 1 public class FullautoWashingMachine{
 2     public void addWater(){
 3         System.out.println("手动注水");
 4     }
 5 
 6     public void washing(){
 7         System.out.println("开始洗衣服");
 8     }
 9 
10     public void drainage(){
11         System.out.println("手动排水");
12     }
13 
14     public void dehydration(){
15         System.out.println("手动脱水");
16     }
17     
18     //对外提供的简单接口
19     public void simpleWashing(){
20         this.addWater();
21         this.washing();
22         this.drainage();
23         this.dehydration();
24     }
25 }

      用户使用全自动洗衣机,就只须要调用simyleWashing()就好了。

      从上面能够看出来, 外观模式并无增长新的功能,只是将原来的一些操做封装到一个接口里面,对外提供了一个简单的接口,避免让用户解除到底层,让系统更加容易使用。固然,若是你愿意,对象原来的一些底层功能(addWater()等方法)你仍然能够自由使用,像半自动洗衣机那样,每一步都手动来操做,只不过这样一来,用户就与对象的底层细节耦合在一块儿了。

3. 总结

      总的来讲,适配器模式提供了讲一个接口转换成其余接口的能力,而无需修改原来的接口;外观模式提供简化接口的能力,让使用者与接口内部的细节解耦,符合“最小知道原则”。

4. 参考

<<Head First设计模式>>

相关文章
相关标签/搜索