1. 程式人生 > >設計模式(三):適配器模式

設計模式(三):適配器模式

strong imp 引入 兩個 依賴 提高 復用 三方庫 透明度

介紹

意圖:將類的接口轉換為客戶期望的另一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。是作為兩個不兼容的接口之間的橋梁。
主要解決:主要解決在軟件系統中,常常要將一些"現存的對象"放到新的環境中,而新環境要求的接口是現對象不能滿足的。
何時使用: 1、系統需要使用現有的類,而此類的接口不符合系統的需要。 2、想要建立一個可以重復使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有一致的接口。 3、通過接口轉換,將一個類插入另一個類系中。
如何解決:繼承或依賴(推薦)。
關鍵代碼:適配器繼承或依賴已有的對象,實現想要的目標接口。

現實世界的例子
請註意,您的存儲卡中有一些照片,需要將它們傳輸到計算機上。為了傳輸它們,您需要某種與計算機端口兼容的適配器,以便將存儲卡連接到計算機。在這種情況下,讀卡器是適配器。另一個例子是著名的電源適配器; 三腳插頭不能連接到雙管插座,需要使用電源適配器使其與雙叉插座兼容。另一個例子是翻譯人員將一個人所說的話翻譯給另一個人聽。

簡單來說
適配器模式允許您將其他不兼容的對象包裝在適配器中,以使其與另一個類兼容。

維基百科說

在軟件工程中,適配器模式是一種軟件設計模式,它允許將現有類的接口用作另一個接口。它通常用於使現有類與其他類一起工作而無需修改其源代碼。

實例

假設一個除了會使用劃艇而其他都不會的船長。

首先,我們有接口RowingBoat和FishingBoat。
// 皮艇

public interface RowingBoat {
  void row();
}

// 漁船接口和實現

public interface FishingBoat {
 void sail();
}
public class FishingBoatOperator implements FishingBoat {
  @Override
  public void sail() {
    System.out.printf("The fishing boat is sailing");
  }
}

船長實現劃艇的接口從而能夠移動。

public class Captain implements RowingBoat {

  private RowingBoat rowingBoat;

  public Captain(RowingBoat rowingBoat) {
    this.rowingBoat = rowingBoat;
  }

  @Override
  public void row() {
    rowingBoat.row();
  }
}

現在讓我們說海盜來了,我們的船長需要逃離,但只有漁船可用。我們需要創建一個適配器,允許船長用他的劃艇技能操作漁船。

public class FishingBoatAdapter implements RowingBoat {

  private FishingBoat boat;

  public FishingBoatAdapter() {
    boat = new FishingBoatOperator();
  }

  @Override
  public void row() {
    boat.sail();
  }
}

而現在,Captain可以操縱漁船用來逃避海盜了。

Captain captain = new Captain(new FishingBoatAdapter());
captain.row();

適用場景

使用適配器模式時

  • 您想使用現有的類,其接口與您需要的接口不匹配。
  • 你想創建一個可重用的類,它與不相關或不可預見的類合作,即不一定具有兼容接口的類。
  • 你需要使用幾個現有的子類,但通過對每個子類進行子類化來調整它們的接口是不切實際的。 對象適配器可以調整其父類的接口。
  • 大多數使用第三方庫的應用程序使用適配器作為應用程序和第三方庫之間的中間層,以將應用程序與庫分離。如果必須使用另一個庫,則只需要新庫的適配器,而無需更改應用程序代碼。

結果

類和對象適配器有不同的權衡:
類適配器

  • 通過承諾具體的Adaptee類來使Adaptee適應Target。因此,當我們想要調整類及其所有子類時,類適配器將不起作用。
  • 讓適配器覆蓋Adaptee的一些行為,因為Adapter是Adaptee的子類。
  • 只引入一個對象,並且不需要額外的指針間接來到適配器。

對象適配器

  • 讓一個適配器與許多Adaptee一起工作 - 即Adaptee本身及其所有子類(如果有的話)。適配器還可以立即向所有Adaptee添加功能。
  • 使得覆蓋Adaptee行為變得更加困難。它將需要子類化Adaptee並使Adapter引用子類而不是Adaptee本身。

總結

優點: 1、可以讓任何兩個沒有關聯的類一起運行。 2、提高了類的復用。 3、增加了類的透明度。 4、靈活性好。
缺點: 1、過多地使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是 A 接口,其實內部被適配成了 B 接口的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。 2.由於 JAVA 至多繼承一個類,所以至多只能適配一個適配者類,而且目標類必須是抽象類。
註意事項:適配器不是在詳細設計時添加的,而是解決正在服役的項目的問題。

  • 翻譯: iluwatar-java-design-patterns
  • 參考:runoob.com

設計模式(三):適配器模式