深入浅出适配器模式

很多时候在说适配器模式,对他也是一知半解,书上的东西理论性太强,读起来不直观,现在通过一个简单的例子来记录一下适配器模式的用法。

假设我们现在有一个需求,要提供一种直观的方式,查看到新上线的游戏中每个服的在线人数。对于每个服来说,已经提供了相应的接口统计在线人数,只需要调用Utility.getOnlinePlayerCount(int),传入每个服对应的数值就可以获取到相应服在线玩家的数量了,如一服传入1,二服传入2,三服则传入3。如果传入了一个不存在的服,则会返回-1。然后只要将得到的数据拼装成XML就OK。

定义好了需求,我们就开始敲代码吧;

首先定义一个用于统计在线人数的接口PlayerCount,代码如下:

[java]  view plain copy
  1. public interface PlayerCount {  
  2.   
  3.     String getServerName();  
  4.   
  5.     int getPlayerCount();  
  6.   
  7. }  
接着定义三个统计类实现了PlayerCount接口,分别对应了三个不同的服,如下所示:
[java]  view plain copy
  1. public class ServerOne implements PlayerCount {  
  2.   
  3.     @Override  
  4.     public String getServerName() {  
  5.         return "一服";  
  6.     }  
  7.   
  8.     @Override  
  9.     public int getPlayerCount() {  
  10.         return Utility.getOnlinePlayerCount(1);  
  11.     }  
  12.   
  13. }  
[java]  view plain copy
  1. public class ServerTwo implements PlayerCount {  
  2.   
  3.     @Override  
  4.     public String getServerName() {  
  5.         return "二服";  
  6.     }  
  7.   
  8.     @Override  
  9.     public int getPlayerCount() {  
  10.         return Utility.getOnlinePlayerCount(2);  
  11.     }  
  12.   
  13. }  
[java]  view plain copy
  1. public class ServerThree implements PlayerCount {  
  2.   
  3.     @Override  
  4.     public String getServerName() {  
  5.         return "三服";  
  6.     }  
  7.   
  8.     @Override  
  9.     public int getPlayerCount() {  
  10.         return Utility.getOnlinePlayerCount(3);  
  11.     }  
  12.   
  13. }  
然后定义一个XMLBuilder类,用于将各服的数据封装成XML格式,代码如下:
[java]  view plain copy
  1. public class XMLBuilder {  
  2.   
  3.     public static String buildXML(PlayerCount player) {  
  4.         StringBuilder builder = new StringBuilder();  
  5.         builder.append("<root>");  
  6.         builder.append("<server>").append(player.getServerName()).append("</server>");  
  7.         builder.append(<player_count").append(player.getPlayerCount()).append(
  8. </player_count>");  
  9.         builder.append("</root>");  
  10.         return builder.toString();  
  11.     }  
  12.   
  13. }  
这样的话,所有代码就完工了,如果你想查看一服在线玩家数只需要调用:
[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,查看二服和三服都很正常。为什么会这样呢?

原來是一服已经开放一段时间了,查询在线玩家数量的功能早就有了,使用的是ServerFirst这个类。当时写Utility.getOnlinePlayerCount()这个方法主要是为了针对新开的二服和三服,就没把一服的查询功能再重复做一遍。

那修改一下Utility.getOnlinePlayerCount()就好了,接下來应该没什么事了吧?

可是,Utility和ServerFirst这两个类都已经被打到Jar包里了,没法修改。

这种情况下就可以使用适配器模式,这个模式就是为了解决接口之间不兼容的问题而出现的。

其实适配器模式的使用非常简单,核心思想就是只要能让两个互不兼容的接口能正常对接就行了。上面的代码中,XMLBuilder中使用PlayerCount这个接口来拼装XML,而ServerFirst并没有实现PlayerCount这个接口,这个时候就需要一个适配器类来为XMLBuilder和ServerFirst之间搭起一座桥梁,毫无疑问,ServerOne就将充当适配器类的角色。修改ServerOne的代码,如下所示:

[java]  view plain copy
  1. public class ServerOne implements PlayerCount {  
  2.       
  3.     private ServerFirst mServerFirst;  
  4.       
  5.     public ServerOne() {  
  6.         mServerFirst = new ServerFirst();  
  7.     }  
  8.   
  9.     @Override  
  10.     public String getServerName() {  
  11.         return "一服";  
  12.     }  
  13.   
  14.     @Override  
  15.     public int getPlayerCount() {  
  16.         return mServerFirst.getOnlinePlayerCount();  
  17.     }  
  18.   
  19. }  
这样通过ServerOne的适配,XMLBuilder和ServerFirst之间就成功完成对接了!使用的时候我们甚至无需知道有ServerFirst这个类,只需要正常创建ServerOne的实例就行了。

需要值得注意的一点是,适配器模式不并是那种会让架构变得更合理的模式,更多的时候它只是充当救火队员的角色,帮助解决由于前期架构设计不合理导致的接口不匹配的问题。更好的做法是在设计的时候就尽量把以后可能出现的情况多考虑一些,在这个问题上不要向你的leader学习。

适配器:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值