標籤:
適配器模式(Adapter):
1、概念:將一個類中的介面轉換為客戶希望的另外一個介面,使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
2、模式中的角色
1 目標介面:客戶所期待的介面。目標可以是具體的或抽象的類,也可以是介面。
2 需要適配的類:需要適配的類或適配者類。
3 適配器:通過封裝一個需要適配的對象,把原介面轉換成目標介面。
3、實現方式
1 類的適配器模式(採用繼承實現)
2 對象適配器(採用對象組合方式實現)
4 代碼
1.類適配器, 適配器類,既繼承了被適配類,又同時實現標準介面
1 //已存在的、具有特殊功能、但不符合我們既有的標準介面的類 2 class Adaptee { 3 public void specificRequest() { 4 System.out.println("需要適配的類"); 5 } 6 } 7 8 // 目標介面 9 interface Target { 10 public void request(); 11 } 12 13 // 具體目標類,只提供普通功能 14 class ConcreteTarget implements Target { 15 public void request() { 16 System.out.println("原來存在的類"); 17 } 18 } 19 20 // 適配器類,繼承了被適配類,同時實現標準介面 21 class Adapter extends Adaptee implements Target{ 22 public void request() { 23 super.specificRequest(); 24 } 25 } 26 27 // 測試類別
28 public static void main(String[] args) { 29 // 使用普通功能類 30 Target concreteTarget = new ConcreteTarget(); 31 concreteTarget.request(); 32 33 // 使用特殊功能類,即適配類 34 Target adapter = new Adapter(); 35 adapter.request(); 36 } 37 }
2 對象適配器
1 public class Test12 { 2 public static void main(String[] args) { 3 //原介面的調用方式 4 PowerA a=new PowerAImpl(); 5 input(a); 6 7 PowerB b=new PowerBImpl(); 8 //input(B);不能用,因為input方法只能接受PowerA介面 9 PowerAdapter adapter=new PowerAdapter(b);10 input(adapter);11 }12 //系統的方法與B介面不相容,但是需要繼續使用13 public static void input(PowerA a){14 a.connect();15 }16 }17 //適配器,可以適配電源A適配器18 class PowerAdapter implements PowerA{19 // 直接關聯被適配介面20 private PowerB b;21 public PowerAdapter(PowerB b){22 this.b=b;23 24 }25 //在適配器裡調用介面B的方法26 @Override27 public void connect() {28 b.insert(); 29 }30 31 }32 33 //需要適配的介面B34 interface PowerB{35 public void insert();36 }37 class PowerBImpl implements PowerB{38 39 @Override40 public void insert() {41 System.out.println("電源B介面開始工作"); 42 }43 44 }45 46 //電源A介面,系統原有介面47 interface PowerA{48 public void connect();49 }50 class PowerAImpl implements PowerA{51 52 @Override53 public void connect() {54 System.out.println("電源A介面開始工作"); 55 }56 57 }
5 總結
(1)類適配器使用對象繼承的方式,是靜態定義方式;而對象適配器使用對象組合的方式,是動態組合的方式。
(2)對於類適配器,由於適配器直接繼承了Adaptee,使得適配器不能和Adaptee的子類一起工作,因為繼承是靜態關係,當適配器繼承了Adaptee後,就不可能再去處理 Adaptee的子類了。
對於對象適配器,一個適配器可以把多種不同的源適配到同一個目標。換言之,同一個適配器可以把源類和它的子類都適配到目標介面。因為對象適配器採用的是對象組合的關係,只要物件類型正確,是不是子類都無所謂。
(3)對於類適配器,適配器可以重定義Adaptee的部分行為,相當於子類覆蓋父類的部分實現方法。
對於對象適配器,要重定義Adaptee的行為比較困難,這種情況下,需要定義Adaptee的子類來實現重定義,然後讓適配器組合子類。雖然重定義Adaptee的行為比較困難,但是想要增加一些新的行為則方便的很,而且新增加的行為可同時適用於所有的源。
(4)對於類適配器,僅僅引入了一個對象,並不需要額外的引用來間接得到Adaptee。
對於對象適配器,需要額外的引用來間接得到Adaptee。
建議盡量使用對象適配器的實現方式,多用合成/彙總、少用繼承。當然,具體問題具體分析,根據需要來選用實現方式,最適合的才是最好的。
適配器模式的優點
更好的複用性
系統需要使用現有的類,而此類的介面不符合系統的需要。那麼通過適配器模式就可以讓這些功能得到更好的複用。
更好的擴充性
在實現適配器功能的時候,可以調用自己開發的功能,從而自然地擴充系統的功能。
適配器模式的缺點
過多的使用適配器,會讓系統非常零亂,不易整體進行把握。比如,明明看到調用的是A介面,其實內部被適配成了B介面的實現,一個系統如果太多出現這種情況,無異於一場災難。因此如果不是很有必要,可以不使用適配器,而是直接對系統進行重構。
Java模式—適配器模式