轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/9400153
此為Java設計模式透析的拷貝版,專門為Ruby愛好者提供的,不熟悉Ruby文法的朋友請轉閱 :
Java設計模式透析之 —— 適配器(Adapter)
今天一大早,你的leader就匆匆忙忙跑過來找到你:“快,快,緊急任務!最近ChinaJoy馬上就要開始了,老闆要求提供一種直觀的方式,可以查看到我們新上線的遊戲中每個服的線上人數。”
你看了看日期,不是吧!這哪裡是馬上要開始了,分明是已經開始了!這怎麼可能來得及呢?
“沒關係的。”你的leader安慰你道:“功能其實很簡單的,介面都已經提供好了,你只需要調用一下就行了。”
好吧,你勉為其難地接受了,對於這種突如其來的新需求,你早已習慣。
你的leader向你具體描述了一下需求,你們的遊戲目前有三個服,一服已經開放一段時間了,二服和三服都是新開的服。設計的介面非常輕便,你只需要調用Utility.online_player_count(Fixnum),傳入每個服對應的數值就可以擷取到相應服線上玩家的數量了,如一服傳入1,二服傳入2,三服則傳入3。如果你傳入了一個不存在的服,則會返回-1。然後你只要將得到的資料拼裝成XML就好,具體的顯示功能由你的leader來完成。
好吧,聽起來功能並不是很複雜,如果現在就開始動工好像還來得及,於是你馬上敲起了代碼。
首先定義一個用於統計線上人數的父類PlayerCount,代碼如下:
class PlayerCountdef server_nameraise "You should override this method in subclass."enddef player_countraise "You should override this method in subclass."endend
接著定義三個統計類繼承PlayerCount,分別對應了三個不同的服,如下所示:
class ServerOne < PlayerCountdef server_name"一服"enddef player_countUtility.online_player_count(1)endend
class ServerTwo < PlayerCountdef server_name"二服"enddef player_countUtility.online_player_count(2)endend
class ServerThree < PlayerCountdef server_name"三服"enddef player_countUtility.online_player_count(3)endend
然後定義一個XMLBuilder類,用於將各服的資料封裝成XML格式,代碼如下:
class XMLBuilderdef self.build_xml playerbuilder = ""builder << "<root>"builder << "<server>" << player.server_name << "</server>"builder << "<player_count>" << player.player_count.to_s << "</player_count>"builder << "</root>"endend
這樣的話,所有代碼就完工了,如果你想查看一服線上玩家數只需要調用:
XMLBuilder.build_xml(ServerOne.new)
查看二服線上玩家數只需要調用:
XMLBuilder.build_xml(ServerTwo.new)
查看三服線上玩家數只需要調用:
XMLBuilder.build_xml(ServerThree.new)
咦?你發現查看一服線上玩家數的時候,傳回值永遠是-1,查看二服和三服都很正常。
你只好把你的leader叫了過來:“我感覺我寫的代碼沒有問題,但是查詢一服線上玩家數總是返回-1,為什麼會這樣呢?”
“哎呀!”你的leader猛然想起,“這是我的問題,前面沒跟你解釋清楚。由於我們的一服已經開放一段時間了,查詢線上玩家數量的功能早就有了,使用的是ServerFirst這個類。當時寫Utility.online_player_count()這個方法主要是為了針對新開的二服和三服,就沒把一服的查詢功能再重複做一遍。這種情況下可以使用適配器模式,這個模式就是為瞭解決介面之間不相容的問題而出現的。”
其實適配器模式的使用非常簡單,核心思想就是只要能讓兩個互不相容的介面能正常對接就行了。上面的代碼中,XMLBuilder中使用PlayerCount來拼裝XML,而ServerFirst並沒有繼承PlayerCount,這個時候就需要一個適配器類來為XMLBuilder和ServerFirst之間搭起一座橋樑,毫無疑問,ServerOne就將充當適配器類的角色。修改ServerOne的代碼,如下所示:
class ServerOne < PlayerCountdef initialize@serverFirst = ServerFirst.newenddef server_name"一服"enddef player_count@serverFirst.online_player_countendend
這樣通過ServerOne的適配,XMLBuilder和ServerFirst之間就成功完成對接了!使用的時候我們甚至無需知道有ServerFirst這個類,只需要正常建立ServerOne的執行個體就行了。
需要值得注意的一點是,適配器模式不並是那種會讓架構變得更合理的模式,更多的時候它只是充當救火隊員的角色,協助解決由於前期架構設計不合理導致的介面不匹配的問題。更好的做法是在設計的時候就盡量把以後可能出現的情況多考慮一些,在這個問題上不要向你的leader學習。
適配器:將一個類的介面轉換成客戶希望的另外一個介面。適配器模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。