設計模式之適配器模式
功能:
將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
適用場景:
1、已經存在的類的接口不符合我們的需求;
2、創建一個可以複用的類,使得該類可以與其他不相關的類或不可預見的類(即那些接口可能不一定兼容的類)協同工作;
3、在不對每一個都進行子類化以匹配它們的接口的情況下,使用一些已經存在的子類。
類適配器
// 具有特殊功能、但不符合我們既有的標準接口的類
class Adaptee {
public void specificRequest() {
System.out.println("被適配類具有 特殊功能...");
}
}
// 目標接口,或稱爲標準接口
interface Target {
public void request();
}
// 具體目標類,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通類 具有 普通功能...");
}
}
// 適配器類,繼承了被適配類,同時實現標準接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
}
// 測試類
public class Client {
public static void main(String[] args) {
// 使用普通功能類
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能類,即適配類
Target adapter = new Adapter();
adapter.request();
}
}
對象適配器
// 適配器類,直接關聯被適配類,同時實現標準接口
class Adapter implements Target{
// 直接關聯被適配類
private Adaptee adaptee;
// 可以通過構造函數傳入具體需要適配的被適配類對象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
}
public void request() {
// 這裏是使用委託的方式完成特殊功能
this.adaptee.specificRequest();
}
}
// 測試類
public class Client {
public static void main(String[] args) {
// 使用普通功能類
Target concreteTarget = new ConcreteTarget();
concreteTarget.request();
// 使用特殊功能類,即適配類,
// 需要先創建一個被適配類的對象作爲參數
Target adapter = new Adapter(new Adaptee());
adapter.request();
}
}
類適配器和對象適配器的權衡
● 類適配器使用對象繼承的方式,是靜態的定義方式;而對象適配器使用對象組合的方式,是動態組合的方式。
● 對於類適配器,由於適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因爲繼承是靜態的關係,當適配器繼承了Adaptee後,就不可能再去處理 Adaptee的子類了。
對於對象適配器,一個適配器可以把多種不同的源適配到同一個目標。換言之,同一個適配器可以把源類和它的子類都適配到目標接口。因爲對象適配器採用的是對象組合的關係,只要對象類型正確,是不是子類都無所謂。
● 對於類適配器,適配器可以重定義Adaptee的部分行爲,相當於子類覆蓋父類的部分實現方法。
對於對象適配器,要重定義Adaptee的行爲比較困難,這種情況下,需要定義Adaptee的子類來實現重定義,然後讓適配器組合子類。雖然重定義Adaptee的行爲比較困難,但是想要增加一些新的行爲則方便的很,而且新增加的行爲可同時適用於所有的源。
● 對於類適配器,僅僅引入了一個對象,並不需要額外的引用來間接得到Adaptee。
對於對象適配器,需要額外的引用來間接得到Adaptee。
建議儘量使用對象適配器的實現方式,多用合成/聚合、少用繼承。當然,具體問題具體分析,根據需要來選用實現方式,最適合的纔是最好的。
適配器模式的優點
更好的複用性
系統需要使用現有的類,而此類的接口不符合系統的需要。那麼通過適配器模式就可以讓這些功能得到更好的複用。
更好的擴展性
在實現適配器功能的時候,可以調用自己開發的功能,從而自然地擴展系統的功能。
適配器模式的缺點
過多的使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是A接口,其實內部被適配成了B接口的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。