適配器模式和外觀模式

      適配器模式提供了將一種對象轉換成另外一種對象的能力,利用它能夠實現兩個不兼容接口的協調工做。外觀模式是封裝對象內的複雜邏輯,對外提供一個簡化的接口。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設計模式>>

相關文章
相關標籤/搜索