转载请注明出处: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. JS中5秒中跳转到其他页面

    原文:JS中5秒中跳转到其他页面 <head> <meta http-equiv="Content-Type" content="text/html; ...

  2. 加载xib文件的两种方式

    一.加载xib文件的两种方式 1.方法一(NewsCell是xib文件的名称) NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@&quo ...

  3. GhostDoc的使用

    原文:GhostDoc的使用 一.简介 GhostDoc是Visual Studio的一个免费插件,可以为开发人员自动生成XML格式的注释文档. 二.下载 需要的朋友可以去这里下载,填个Email地址 ...

  4. JS模块与命名空间的介绍二

    区别一:

  5. 安卓CTS官方文档之兼容性方案概览

    兼容性方案概览 安卓的兼容性方案让安卓手机生产商能够很容易就开发中可兼容的安卓设备(天地会珠海分舵注:可兼容什么呢?就是可以兼容标准google提供的安卓系统可以支持的功能,以防手机生产商把开源的安卓 ...

  6. C++ AMP 介绍(两)

    C++ AMP 介绍(两) 最后更新:2014-05-02 读前提:<C++ AMP介绍(一个)> 周边环境:Windows 8.1 64bit英文版,Visual Studio 2013 ...

  7. 经典的SQL语句面试题

    Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题 ...

  8. 微软Visual Studio "14" CTP 2 发布

    微软Visual Studio "14" CTP 2 发布 对于在微软阵营下进行工作的团队来说,拥有最新版本的Visual Studio是提高效率最佳的选择,没有之一. 在本文中, ...

  9. 路由模块router实现step1

    hashchange事件 参考:http://www.cnblogs.com/rubylouvre/archive/2012/10/24/2730599.html 需要解决的问题: 1.IE6/7及兼 ...

  10. Android 5.0自定义动画

    材料设计中的动画对用户的操作给予了反馈,并且在与应用交互时提供了持续的可见性.材料主题提供了一些按钮动画和活动过渡,Android 5.0允许你自定义动画并且可以创建新的动画: Touch Feedb ...