转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400141

今天一大早,你的leader就匆匆忙忙跑过来找到你:“快,快,紧急任务!最近ChinaJoy马上就要开始了,老板要求提供一种直观的方式,可以查看到我们新上线的游戏中每个服的在线人数。”

你看了看日期,不是吧!这哪里是马上要开始了,分明是已经开始了!这怎么可能来得及呢?

“没关系的。”你的leader安慰你道:“功能其实很简单的,接口都已经提供好了,你只需要调用一下就行了。”

好吧,你勉为其难地接受了,对于这种突如其来的新需求,你早已习惯。

你的leader向你具体描述了一下需求,你们的游戏目前有三个服,一服已经开放一段时间了,二服和三服都是新开的服。设计的接口非常轻便,你只需要调用Utility.getOnlinePlayerCount(int),传入每个服对应的数值就可以获取到相应服在线玩家的数量了,如一服传入1,二服传入2,三服则传入3。如果你传入了一个不存在的服,则会返回-1。然后你只要将得到的数据拼装成XML就好,具体的显示功能由你的leader来完成。

好吧,听起来功能并不是很复杂,如果现在就开始动工好像还来得及,于是你马上敲起了代码。

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

public interface PlayerCount {

	String getServerName();

	int getPlayerCount();

}

接着定义三个统计类实现了PlayerCount接口,分别对应了三个不同的服,如下所示:

public class ServerOne implements PlayerCount {

	@Override
public String getServerName() {
return "一服";
} @Override
public int getPlayerCount() {
return Utility.getOnlinePlayerCount(1);
} }
public class ServerTwo implements PlayerCount {

	@Override
public String getServerName() {
return "二服";
} @Override
public int getPlayerCount() {
return Utility.getOnlinePlayerCount(2);
} }
public class ServerThree implements PlayerCount {

	@Override
public String getServerName() {
return "三服";
} @Override
public int getPlayerCount() {
return Utility.getOnlinePlayerCount(3);
} }

然后定义一个XMLBuilder类,用于将各服的数据封装成XML格式,代码如下:

public class XMLBuilder {

	public static String buildXML(PlayerCount player) {
StringBuilder builder = new StringBuilder();
builder.append("<root>");
builder.append("<server>").append(player.getServerName()).append("</server>");
builder.append("<player_count").append(player.getPlayerCount()).append("</player_count>");
builder.append("</root>");
return builder.toString();
} }

这样的话,所有代码就完工了,如果你想查看一服在线玩家数只需要调用:

XMLBuilder.buildXML(new ServerOne());

查看二服在线玩家数只需要调用:

XMLBuilder.buildXML(new ServerTwo());

查看三服在线玩家数只需要调用:

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的代码,如下所示:

public class ServerOne implements PlayerCount {

	private ServerFirst mServerFirst;

	public ServerOne() {
mServerFirst = new ServerFirst();
} @Override
public String getServerName() {
return "一服";
} @Override
public int getPlayerCount() {
return mServerFirst.getOnlinePlayerCount();
} }

这样通过ServerOne的适配,XMLBuilder和ServerFirst之间就成功完成对接了!使用的时候我们甚至无需知道有ServerFirst这个类,只需要正常创建ServerOne的实例就行了。

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

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

Java设计模式透析之 —— 适配器(Adapter)的更多相关文章

  1. Ruby设计模式透析之 —— 适配器(Adapter)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  2. Java设计模式透析之 —— 单例(Singleton)

    写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...

  3. Java设计模式透析之 —— 策略(Strategy)

    今天你的leader兴致冲冲地找到你,希望你能够帮他一个小忙.他如今急着要去开会.要帮什么忙呢?你非常好奇. 他对你说.当前你们项目的数据库中有一张用户信息表.里面存放了非常用户的数据.如今须要完毕一 ...

  4. Java设计模式透析之 —— 模板方法(Template Method)

    今天你还是像往常一样来上班,一如既往地開始了你的编程工作. 项目经理告诉你,今天想在server端添加一个新功能.希望写一个方法.能对Book对象进行处理.将Book对象的全部字段以XML格式进行包装 ...

  5. Java设计模式透析之 —— 组合(Composite)

    听说你们公司最近新推出了一款电子书阅读应用,市场反应很不错,应用里还有图书商城,用户可以在其中随意选购自己喜欢的书籍.你们公司也是对此项目高度重视,加大了投入力度,决定给此应用再增加点功能. 好吧,你 ...

  6. Ruby设计模式透析之 —— 组合(Composite)

    转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...

  7. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  8. 设计模式C++描述----06.适配器(Adapter)模式

    一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...

  9. Headfirst设计模式的C++实现——适配器(Adapter)

    duck.h #ifndef _DUCK_H_ #define _DUCK_H_ class DUCK { public: ; ; }; #endif mallard_duck.h #ifndef _ ...

随机推荐

  1. select查询原理

    原文:select查询原理 我并非专业DBA,但做为B/S架构的开发人员,总是离不开数据库,一般开发员只会应用SQL的四条经典语句:select ,insert,delete,update.但是我从来 ...

  2. Node.js与MongoDB的基本连接示例

    Node.js与MongoDB的基本连接示例 前提 已经安装了node.js和MongoDB,本文使用的node.js是v0.12.0,MongoDB是3.0.0. 初始化数据 启动MongoDB服务 ...

  3. Android 2.3 版本中链接边框问题解决

    在做移动互联网开发的过程中,同样需要考虑到移动终端(如手机.平板)的不同版本浏览器兼容问题,在Android 2.3 版本的默认浏览器中有一个bug-会自动给所有链接文本在点击操作过程中加黄色或绿色边 ...

  4. 平安某金所奇葩的面经-关于幂等和ROA设计的反思

    在公司一直在做跟支付有关的项目,某日接到平安某金所一男子电话,应该是之前某猎头投的,我正好在吃早饭(也不能怪他们上班早,我们公司弹性工作制,我一般上班比较晚). 因为饭馆信号不好,只能赶紧放下剩下的半 ...

  5. MVC验证05-自定义验证规则、验证2个属性值不等

    原文:MVC验证05-自定义验证规则.验证2个属性值不等 本文体验2个属性值不等.即当一个属性输入值,另外一个属性输入的值不能和第一个属性值相等.相关文章包括: MVC验证01-基础.远程验证   M ...

  6. 【phpMyAdmin】更改配置文件连接到其他server

    默认phpMyAdmin安装完毕后对机器的访问mysql,但有时我们需要访问其它server的mysql数据库,所以我们需要配置. 真,phpMyAdmin已经为我们做了配置的选项.可是须要我们进行一 ...

  7. JVM监控概述(图文)

    JVM内存分配概述 Jvm 内存分为:堆.非堆及直接内存三大块. 堆区分为年轻代和老年代,永生代属于非堆内存. 对象优先在Eden区分配 大对象直接进入老年代 长期存活的对象将进入老年代 class. ...

  8. Cacti+Nagios监控平台完美整合

    Cacti+Nagios监控平台完美整合 本博文出自51CTO博客吴光科博主,有任何问题请进入博主页面互动讨论!博文地址:http://wgkgood.blog.51cto.com/1192594/1 ...

  9. leetcode第24题--Reverse Nodes in k-Group

    problem: Given a linked list, reverse the nodes of a linked list k at a time and return its modified ...

  10. C# 4.0 Parallel

    C# 4.0 并行计算部分   沿用微软的写法,System.Threading.Tasks.::.Parallel类,提供对并行循环和区域的支持. 我们会用到的方法有For,ForEach,Invo ...