1. 程式人生 > >Java設計模式之 — 適配器(Adapter)

Java設計模式之 — 適配器(Adapter)

pri 調用 jar net 方式 需求 inter size 模式

轉載請註明出處:http://blog.csdn.net/guolin_blog/article/details/9400141

今天一大早,你的leader就匆匆忙忙跑過來找到你:“快,快,緊急任務!最近ChinaJoy馬上就要開始了,老板要求提供一種直觀的方式,可以查看到我們新上線的遊戲中每個服的在線人數。”

你看了看日期,不是吧!這哪裏是馬上要開始了,分明是已經開始了!這怎麽可能來得及呢?

“沒關系的。”你的leader安慰你道:“功能其實很簡單的,接口都已經提供好了,你只需要調用一下就行了。”

好吧,你勉為其難地接受了,對於這種突如其來的新需求,你早已習慣。

你的leader向你具體描述了一下需求,你們的遊戲目前有三個服,一服已經開放一段時間了,二服和三服都是新開的服。設計的接口非常輕便,你只需要調用Utility.getOnlinePlayerCount(int),傳入每個服對應的數值就可以獲取到相應服在線玩家的數量了,如一服傳入1,二服傳入2,三服則傳入3。如果你傳入了一個不存在的服,則會返回-1。然後你只要將得到的數據拼裝成XML就好,具體的顯示功能由你的leader來完成。

好吧,聽起來功能並不是很復雜,如果現在就開始動工好像還來得及,於是你馬上敲起了代碼。

首先定義一個用於統計在線人數的接口PlayerCount,代碼如下:

[java] view plain copy
  1. public interface PlayerCount {
  2. String getServerName();
  3. int getPlayerCount();
  4. }

接著定義三個統計類實現了PlayerCount接口,分別對應了三個不同的服,如下所示:

[java] view plain copy
  1. public class ServerOne implements PlayerCount {
  2. @Override
  3. public String getServerName() {
  4. return "一服";
  5. }
  6. @Override
  7. public int getPlayerCount() {
  8. return Utility.getOnlinePlayerCount(1);
  9. }
  10. }
[java] view plain copy
  1. public class ServerTwo implements PlayerCount {
  2. @Override
  3. public String getServerName() {
  4. return "二服";
  5. }
  6. @Override
  7. public int getPlayerCount() {
  8. return Utility.getOnlinePlayerCount(2);
  9. }
  10. }
[java] view plain copy
  1. public class ServerThree implements PlayerCount {
  2. @Override
  3. public String getServerName() {
  4. return "三服";
  5. }
  6. @Override
  7. public int getPlayerCount() {
  8. return Utility.getOnlinePlayerCount(3);
  9. }
  10. }

然後定義一個XMLBuilder類,用於將各服的數據封裝成XML格式,代碼如下:

[java] view plain copy
  1. public class XMLBuilder {
  2. public static String buildXML(PlayerCount player) {
  3. StringBuilder builder = new StringBuilder();
  4. builder.append("<root>");
  5. builder.append("<server>").append(player.getServerName()).append("</server>");
  6. builder.append("<player_count").append(player.getPlayerCount()).append("</player_count>");
  7. builder.append("</root>");
  8. return builder.toString();
  9. }
  10. }

這樣的話,所有代碼就完工了,如果你想查看一服在線玩家數只需要調用:

[java] view plain copy
  1. XMLBuilder.buildXML(new ServerOne());

查看二服在線玩家數只需要調用:

[java] view plain copy
  1. XMLBuilder.buildXML(new ServerTwo());

查看三服在線玩家數只需要調用:

[java] view plain copy
  1. XMLBuilder.buildXML(new ServerThree());

咦?你發現查看一服在線玩家數的時候,返回值永遠是-1,查看二服和三服都很正常。

你只好把你的leader叫了過來:“我感覺我寫的代碼沒有問題,但是查詢一服在線玩家數總是返回-1,為什麽會這樣呢?”

“哎呀!”你的leader猛然想起,“這是我的問題,前面沒跟你解釋清楚。由於我們的一服已經開放一段時間了,查詢在線玩家數量的功能早就有了,使用的是ServerFirst這個類。當時寫Utility.getOnlinePlayerCount()這個方法主要是為了針對新開的二服和三服,就沒把一服的查詢功能再重復做一遍。”

聽到你的leader這麽說,你頓時松了一口氣:“那你修改一下Utility.getOnlinePlayerCount()就好了,應該沒我什麽事了吧?”

“晤。。。本來應該是這樣的。。。可是,Utility和ServerFirst這兩個類都已經被打到Jar包裏了,沒法修改啊。。。”你的leader有些為難。

“什麽?這不是坑爹嗎,難道要我把接口給改了?”你已經淚流滿面了。

“這倒不用,這種情況下可以使用適配器模式,這個模式就是為了解決接口之間不兼容的問題而出現的。”

其實適配器模式的使用非常簡單,核心思想就是只要能讓兩個互不兼容的接口能正常對接就行了。上面的代碼中,XMLBuilder中使用PlayerCount這個接口來拼裝XML,而ServerFirst並沒有實現PlayerCount這個接口,這個時候就需要一個適配器類來為XMLBuilder和ServerFirst之間搭起一座橋梁,毫無疑問,ServerOne就將充當適配器類的角色。修改ServerOne的代碼,如下所示:

[java] view plain copy
  1. public class ServerOne implements PlayerCount {
  2. private ServerFirst mServerFirst;
  3. public ServerOne() {
  4. mServerFirst = new ServerFirst();
  5. }
  6. @Override
  7. public String getServerName() {
  8. return "一服";
  9. }
  10. @Override
  11. public int getPlayerCount() {
  12. return mServerFirst.getOnlinePlayerCount();
  13. }
  14. }

這樣通過ServerOne的適配,XMLBuilder和ServerFirst之間就成功完成對接了!使用的時候我們甚至無需知道有ServerFirst這個類,只需要正常創建ServerOne的實例就行了。

需要值得註意的一點是,適配器模式不並是那種會讓架構變得更合理的模式,更多的時候它只是充當救火隊員的角色,幫助解決由於前期架構設計不合理導致的接口不匹配的問題。更好的做法是在設計的時候就盡量把以後可能出現的情況多考慮一些,在這個問題上不要向你的leader學習。

適配器:將一個類的接口轉換成客戶希望的另外一個接口。適配器模式使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。

Java設計模式之 — 適配器(Adapter)