設計模式(三):介面卡模式
介紹
意圖:將類的介面轉換為客戶期望的另一個介面。介面卡模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。是作為兩個不相容的介面之間的橋樑。
主要解決:主要解決在軟體系統中,常常要將一些"現存的物件"放到新的環境中,而新環境要求的介面是現物件不能滿足的。
何時使用: 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 至多繼承一個類,所以至多隻能適配一個適配者類,而且目標類必須是抽象類。
注意事項:介面卡不是在詳細設計時新增的,而是解決正在服役的專案的問題。
- 翻譯:ofollow,noindex" target="_blank">iluwatar-java-design-patterns
- 參考:runoob.com