<大話設計模式>本教程說明及著作權聲明
國士工作室是一支專註於Android平台企業級應用開發的技術團隊,致力於做中國最棒的Android應用程式開發機構,提供最棒的Android企業級應用開發培訓服務。
企業培訓和開發合作官方連絡方式:
電話:18610086859
Email:hiheartfirst@gmail.com
QQ:1740415547
QQ群:148325348
國士工作室 有你更美好!
l 該文檔參考和使用了網路上的免費開放的圖片和內容,並以免費開放的方式發布,希望為移動互連網和智能手機時代貢獻綿薄之力!可以隨意轉載,但不得使用該文檔謀利。
l 如果對該文檔有任何疑問或者建議,請進入官方部落格
http://www.cnblogs.com/guoshiandroid/留言或者直接與國士工作室聯絡(後附連絡方式),我們會謹慎參考您的建議並根據需要對本文檔進行修改,以造福更多開發人員!
l 《大話設計模式》的最新及完整內容會在國士工作室官方部落格定期更新,請訪問國士工作室部落格
http://www.cnblogs.com/guoshiandroid/擷取更多更新內容。
適配器模式 膝上型電腦的適配器
適配器模式應用情境舉例:
MM的表格炒股發的一塌糊塗,答應MM送她一款筆記本。這下可把MM樂壞了^_^不過因為表哥和MM上學的學校不在同一個城市,所以筆記本需要郵寄過來。幾天后,MM終於收到了筆記本,快要開心死了!但當MM正要查看電腦的實際運行效果的時候,卻發現插頭不對,無法插進去!哈哈,MM欲哭無淚,立即打電話給GG。GG在得知了事情的詳細經過後,笑著說道:“傻瓜,別急,我去給你買一個插頭轉換器不久OK了嗎”,說完,GG就跑到科技市場,尋找適合MM電腦的插頭轉換器,也不知道MM的表哥在哪裡買的這個電腦,問了好幾個店鋪都沒找到合適的,GG心想,如果買不到就無法回去向MM交代啊。最終在GG千辛萬苦的努力下還是買到了。當MM終於能夠使用電腦的時候,給GG發了一條簡訊“親愛的,愛死你了,下輩子還愛你!”。
適配器模式解釋:
適配器模式(Adapter Pattern):將一個類的介面轉換成客戶希望的另外一個介面。Adapter模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
適配器分為對象適配器和類適配器。
對象適配器使用組合方式,不僅可以適配某個類,也可以適配該類的任何子類,如果子類中加入新的行為,只需要讓組合對象是子類就可以解決靈活性的問題;而類適配器因為採用的是繼承的方式,所以只能夠採用某個特定的被適配類,這就有一個很大的優點,那就是不需要實現整個被適配類,而且在必要的時候還可以覆蓋被適配者的行為。
英文定義為:Convert the interface of a class into another interface clients
expect.
適配器模式的UML圖:
類適配的UML圖如下 所示:
類適配器所涉及的角色如下:
目標(Target)角色:是用戶端期待得到的介面。因為這裡討論的是類適配器,又由於Java語言單繼承的屬性,因此,目標角色不可以是類。
源(Adaptee)角色:需要適配的介面,就是被適配的對象。
適配器(Adapter)角色:這是類適配器模式的核心。適配器把源介面轉換成目標介面,很顯然,適配器角色不可以是介面,而必須是具體的類。
對象適配器的UML圖如下所示:
對象適配器所涉及的角色如下:
目標(Target)角色:是用戶端期待得到的介面。目標角色可以是具體類也可以是抽象類別。
源(Adaptee)角色:需要適配的介面,就是被適配的對象。
適配器(Adapter)角色:這是對象適配器模式的核心。適配器把源介面轉換成目標介面,很顯然,適配器角色不可以是介面,而必須是具體的類。
適配器模式深入分析:
我們經常碰到要將兩個沒有關係的類組合在一起使用,第一解決方案是:修改各自類的介面,但是如果我們沒有原始碼,或者,我們不願意為了一個應用而修改各自的介面。這時候就不能夠採用此種方案了,而且修改源碼必然的要影響到和這些類相關的類和對象;第二種方式:使用一個適配器,把原來的介面轉變為客戶所需要的目標介面,在源介面和用戶端之間建立一座橋樑,是源介面不用做任何修改就可被目標介面使用。
適配器模式的目的在於:如果客戶需要使用某個類的服務,而這項服務是這個類用一個不同的介面提供的,那麼,可以使用適配器為客戶提供一個期望的介面。
用戶端使用適配器的具體過程如下:
第一步:用戶端通過目標介面調用適配器的方法對適配器發出請求。
第二步:適配器使用被適配介面把請求轉換成被適配器者的一個或者多個調用介面。
第三步:用戶端收到調用的結果,但是並未覺察到這一切是適配器在起轉換作用。
一般情況下而言,筆者更提倡使用對象適配器,這是因為對象適配器符合良好的物件導向的設計原則,對象適配器使用對象組合,用對用戶端適用的介面來封裝被適配者,這種做法帶來的另外一個優點是使用於被適配這的地方,也適用於被適配者的任何子類;而如果使用類適配器的話,就會喪失這種靈活性,同時類適配是的目標角色不可以是類,因為Java是單繼承語言。
適配器模式使用情境分析及代碼實現:
在上面的使用情境中,MM的膝上型電腦的電源插頭不可以正常使用,也即是說筆記本的插頭和MM學校寢室的介面不相符合,於是GG就到可以市場買了一個適合MM的筆記本和寢室電源介面的轉換器,這個轉換器插頭就是適配器。
建立一個寢室的電源類:
package com.diermeng.designPattern.Adapter.impl; /* * 電源 */ public class Current { /* * 電源電壓 */ public void use220V() { System.out.println("寢室電源電壓是220V^_^"); } } |
建立一個類適配器:
package com.diermeng.designPattern.Adapter.impl; /* * 類適配器 使用了繼承的方式 */ public class AdapterClass extends Current{ /* * 用戶端期望的介面 */ public void use18V() { System.out.println("我是類適配器"); //調用Current的方法 this.use220V(); } } |
建立類適配器的測試用戶端:
package com.diermeng.designPattern.Adapter.client; import com.diermeng.designPattern.Adapter.impl.AdapterClass; /* * 類適配器用戶端測試 */ public class AdapterClassTest { public static void main(String[] args) { //執行個體化類適配器 AdapterClass adapter = new AdapterClass(); //調用類適配器對用戶端提供的方法 adapter.use18V(); } } |
運行結果如下:
建立對象適配器:
package com.diermeng.designPattern.Adapter.impl; /* * 對象適配器 */ public class AdapterObject { /* * 對源目標的引用 */ private Current current; /* * 在構造方法中執行個體化current */ public AdapterObject(Current current) { this.current = current; } /* * 對象適配器提供的對用戶端期望的介面 */ public void use18V() { System.out.println("我是對象使用適配器"); this.current.use220V(); } } |
建立對象適配器的測試用戶端:
package com.diermeng.designPattern.Adapter.client; import com.diermeng.designPattern.Adapter.impl.AdapterObject; import com.diermeng.designPattern.Adapter.impl.Current; /* * 對象適配用戶端測試 */ public class AdapterObjectTest { public static void main(String[] args) { //聲明並執行個體化對象適配器 AdapterObject adapter = new AdapterObject(new Current()); //調用對象適配器對用戶端提供的方法 adapter.use18V(); } } |
對象適配器運行結果:
適配器模式的優缺點分析:
優點:
使用適配器模式,能夠將一個系統的介面和另外一個系統的介面聯絡起來,從而使得原本不可以在一起工作的類能夠在一起工作,適配器模式強調了對介面的轉換。
缺點:
對於類適配器而言,不能夠適配類的子類;而對於對象適配器而言,重新定義被適配類的行為比較的困難,但是也並非說不可能,這個時候需要使用子類繼承的方式來使用修改了被適配類的子類。
適配器模式的實際應用簡介:
在大規模的系統開發過程中,我們常常碰到諸如以下這些情況:我們需要實現某些功能,這些功能已有還不太成熟的一個或多個外部組件,如果我們自己重新開發這些功能會花費大量時間;所以很多情況下會選擇先暫時使用外部組件,以後再考慮隨時替換。但這樣一來,會帶來一個問題,隨著對外部組件庫的替換,可能需要對引用該外部組件的原始碼進行大面積的修改,因此也極可能引入新的問題等等。如何最大限度的降低修改面呢?Adapter模式就是針對這種類似需求而提出來的。Adapter模式通過定義一個新的介面(對要實現的功能加以抽象),和一個實現該介面的Adapter(適配器)類來透明地調用外部組件。這樣替換外部組件時,最多隻要修改幾個Adapter類就可以了,其他原始碼都不會受到影響。
具體來講,Adapter模式可應用於如下的情況:
1、系統需要使用現有的類,而此類的介面不符合系統的需要。
2、想要建立一個可以重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作,這些源類不一定有與一致的介面。這種情況從不同的角度考慮,可能被劃入Facade模式的範疇,但從與現有設計適配的角度考慮該問題,則將其劃歸Adapter模式也是可以理解的。
3、通過介面轉換,將一個類插入另一個類系中。
溫馨提示:
一般情況下而言,筆者更提倡使用對象適配器,這是因為對象適配器符合良好的物件導向的設計原則,對象適配器使用對象組合,用對用戶端適用的介面來封裝被適配者,這種做法帶來的另外一個優點是使用於被適配這的地方,也適用於被適配者的任何子類;而如果使用類適配器的話,就會喪失這種靈活性,同時類適配是的目標角色不可以是類,因為Java是單繼承語言。