Java设计模式-适配器模式Adapter
定義:“轉換接口”
將一個類的接口轉換成客戶希望的另外一個接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以在一起工作。
我理解的“一個類的接口”是被適配對象Adapteede 接口,“客戶希望的另外一個接口”就是客戶端已經的接口,因為客戶端只能適應這一種接口,所以它期望這個接口
實現目標:就是客戶端Client希望通過這個原有的Target接口,實現被適配對象的新功能
模式中的角色:
目標接口(Target):客戶所期待的接口,就是客戶現在有的接口,舊接口。目標可以是具體的或抽象的類,也可以是接口。
? ? 需要適配的類(Adaptee):需要適配的類或適配者類,就是需要的接口,需要用舊接口實現新功能的新接口。
? ? 適配器(Adapter):通過包裝一個需要適配的對象,把原接口轉換成目標接口。
UML圖:
Target.java
/*** */ package com.hust.adapter1;/*** @author tuke**/ public interface Target {public void Request(); } NowConcreteTarget.java
/*** */ package com.hust.adapter1;/*** @author tuke**/ public class NowConcreteTarget implements Target {public void Request() {System.out.println("這是一個現有的具體類,與客戶端相適應的接口,只具有普通功能");}} Adaptee.java
/*** */ package com.hust.adapter1;/*** @author Administrator* 已存在的、具有特殊功能、但不符合我們既有的標準接口的類,被適配的類就是客戶端要通過現有的接口(Target的Request方法)獲得這個被適配的方法SpecificRequest*/ public class Adaptee {public void SpecificRequest(){System.out.println("被適配的類,有特殊功能");} } Adapter.java
/*** */ package com.hust.adapter1;/*** @author tuke* 適配器類,直接關聯被適配類,同時實現標準接口*/ public class Adapter implements Target {//實現現有接口,即標準接口,舊接口,現有接口private Adaptee mAdaptee;//被適配類的對象做成員變量,就是組合不適合現有接口的類的對象public Adapter(Adaptee mAdaptee) { this.mAdaptee = mAdaptee;}public void Request() { // Request是客戶端期待的接口,即是現有接口,舊接口,因為就現在來看,客戶端只能適應這種接口mAdaptee.SpecificRequest(); //SpecificRequest這是新的接口,不適合客戶端的接口,所以要適配,客戶端通過現有接口Request就能實現新的功能}} 自己實踐了一個別人的栗子,很好的栗子。
我們國家的電器使用普通的扁平兩項或三項插頭,而去外國的話,使用的標準就不一樣了,比如德國,使用的是德國標準,是兩項圓頭的插頭。如果去德國旅游,那么我們使用的手機充電器插頭無法插到德國的插排中去,那就意味著我們無法給手機充電。怎樣解決這個問題呢?只要使用一個電源轉化器就行了。
該適配器下面的插頭符合德國標準,可以插到德國的插排中去,上面提供的接口符合國標,可以供我們的手機充電器使用。
實現電源適配器:
1,代碼中有兩個接口,分別為德標接口和國標接口,分別命名為DBSocketInterface和GBSocketInterface,
2.此外還有兩個實現類,分別為德國插座和中國插座,分別為DBSocket和GBSocket。
3,為了提供兩套接口之間的適配,我們提供了一個適配器,叫做SocketAdapter。
4,除此之外,還有一個客戶端,比如是我們去德國旅游時住的一家賓館,叫Hotel,在這個德國旅館中使用德國接口
德國接口:DBSocketInterface.java
package com.hust.adapter2; /*** 德標接口*/ public interface DBSocketInterface {/*** 這個方法的名字叫做:使用兩項圓頭的插口供電* */void powerWithTwoRound(); } DBSocket.java
package com.hust.adapter2;/*** 德國插座*/ public class DBSocket implements DBSocketInterface{public void powerWithTwoRound(){System.out.println("使用兩項圓頭的插孔供電");} }
德國旅館是一個客戶端,它里面有德標的接口,可以使用這個德標接口給手機充電:
package com.hust.adapter2; public class Hotel {//旅館中有一個德標的插口接口private DBSocketInterface dbSocket;public Hotel(){}public Hotel(DBSocketInterface dbSocket) {this.dbSocket = dbSocket;}public void setSocket (DBSocketInterface dbSocket){this.dbSocket = dbSocket;}//旅館中有一個充電的功能public void charge(){//使用德標插口充電dbSocket.powerWithTwoRound();} }
現在寫一段代碼進行測試:
輸出:使用兩項圓頭的插孔供電
現在我去德國旅游,帶去的三項扁頭的手機充電器。如果沒有帶電源適配器,我是不能充電的,因為不可能為了我一個旅客而為我更改墻上的插座,更不可能為我專門蓋一座使用中國國標插座的賓館。
因為人家德國人一直這么使用,并且用的挺好,俗話說入鄉隨俗,我就要自己想辦法來解決問題。對應到我們的代碼中,也就是說,上面的Hotel類,DBSocket類,DBSocketInterface接口都是不可變的(由德國的客戶提供),如果我想使用這一套API,那么只能自己寫代碼解決。?
GBSocketInterface.javapackage com.hust.adapter2; /** 國標接口* */ public interface GBSocketInterface {/*** 這個方法的名字叫做:使用三項扁頭的插口供電*/void powerWithThreeFlat(); } GBSocket.java
package com.hust.adapter2;/*** 中國插座*/ public class GBSocket implements GBSocketInterface{public void powerWithThreeFlat() {System.out.println("使用三項扁頭插孔供電");} }
可以認為這兩個東西是我帶到德國去的,目前他們還不能使用,因為接口不一樣。那么我必須創建一個適配器,這個適配器必須滿足以下條件:
1 ,必須符合德國標準的接口,否則的話還是沒辦法插到德國插座中;?
2 ,在調用上面實現的德標接口進行充電時,提供一種機制,將這個調用轉到對國標接口的調用 。
這就要求:
1 ,適配器必須實現原有的舊的接口?
2, 適配器對象中持有對新接口的引用,當調用舊接口時,將這個調用委托給實現新接口的對象來處理,也就是在適配器對象中組合一個新接口。
SocketAdapter.java
package com.hust.adapter2; /** 插座適配器* */ public class SocketAdapter implements DBSocketInterface{ //實現舊接口,現有接口private GBSocketInterface gbSocket;//組合新接口,不適合現有接口的類,需要被適配的類/*** 在創建適配器對象時,必須傳入一個新街口的實現類* @param gbSocket*/public SocketAdapter(GBSocketInterface gbSocket) {this.gbSocket = gbSocket;}/*** 將對就接口的調用適配到新接口*/public void powerWithTwoRound() {gbSocket.powerWithThreeFlat();} }
下面寫一段測試代碼來驗證一下適配器能不能工作,我們按步驟一步步的寫出代碼,以清楚的說明適配器是如何使用的。
1 我去德國旅游,帶去的充電器是國標的(可以將這里的GBSocket看成是充電器)
//國標插座適配器GBSocketInterface gbSocket = new GBSocket(); 2 來到德國后, 找到一家德國賓館住下 (這個賓館還是上面代碼中的賓館,使用的依然是德國標準的插口)
//客戶端 Hotel hotel = new Hotel(); 3 由于沒法充電,我拿出隨身帶去的適配器,并且將我帶來的充電器插在適配器的上端插孔中。這個上端插孔是符合國標的,我的充電器完全可以插進去。
//插座適配器 SocketAdapter socketAdapter = new SocketAdapter(gbSocket); 4 再將適配器的下端插入賓館里的插座上
//客戶端設置適配器hotel.setSocket(socketAdapter); 5 可以在賓館中使用適配器進行充電了
//調用客戶端的原有接口,但是有了適配器,適配了不合適的類,使用的是同一個方法就有了新功能hotel.charge(); 這個栗子對理解適配器模式很好,貼近生活。
TestAdapter.java
package com.hust.adapter2;public class TestAdapter {public static void main(String[] args) {//國標插座適配器GBSocketInterface gbSocket = new GBSocket();//客戶端Hotel hotel = new Hotel(); //插座適配器SocketAdapter socketAdapter = new SocketAdapter(gbSocket);//客戶端設置適配器hotel.setSocket(socketAdapter); //調用客戶端的原有接口,但是有了適配器,適配了不合適的類,使用的是同一個方法就有了新功能hotel.charge();} }
參考:http://www.2cto.com/kf/201401/275535.html
總結
以上是生活随笔為你收集整理的Java设计模式-适配器模式Adapter的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Eclipse内存分析工具的用法
- 下一篇: Scanner的next,nextint