Ruby设计模式透析之 —— 适配器(Adapter)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400153
此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉Ruby语法的朋友请转阅 :
今天一大早,你的leader就匆匆忙忙跑过来找到你:“快,快,紧急任务!最近ChinaJoy马上就要开始了,老板要求提供一种直观的方式,可以查看到我们新上线的游戏中每个服的在线人数。”
你看了看日期,不是吧!这哪里是马上要开始了,分明是已经开始了!这怎么可能来得及呢?
“没关系的。”你的leader安慰你道:“功能其实很简单的,接口都已经提供好了,你只需要调用一下就行了。”
好吧,你勉为其难地接受了,对于这种突如其来的新需求,你早已习惯。
你的leader向你具体描述了一下需求,你们的游戏目前有三个服,一服已经开放一段时间了,二服和三服都是新开的服。设计的接口非常轻便,你只需要调用Utility.online_player_count(Fixnum),传入每个服对应的数值就可以获取到相应服在线玩家的数量了,如一服传入1,二服传入2,三服则传入3。如果你传入了一个不存在的服,则会返回-1。然后你只要将得到的数据拼装成XML就好,具体的显示功能由你的leader来完成。
好吧,听起来功能并不是很复杂,如果现在就开始动工好像还来得及,于是你马上敲起了代码。
首先定义一个用于统计在线人数的父类PlayerCount,代码如下:
class PlayerCount def server_name
raise "You should override this method in subclass."
end def player_count
raise "You should override this method in subclass."
end end
接着定义三个统计类继承PlayerCount,分别对应了三个不同的服,如下所示:
class ServerOne < PlayerCount def server_name
"一服"
end def player_count
Utility.online_player_count(1)
end end
class ServerTwo < PlayerCount def server_name
"二服"
end def player_count
Utility.online_player_count(2)
end end
class ServerThree < PlayerCount def server_name
"三服"
end def player_count
Utility.online_player_count(3)
end end
然后定义一个XMLBuilder类,用于将各服的数据封装成XML格式,代码如下:
class XMLBuilder def self.build_xml player
builder = ""
builder << "<root>"
builder << "<server>" << player.server_name << "</server>"
builder << "<player_count>" << player.player_count.to_s << "</player_count>"
builder << "</root>"
end end
这样的话,所有代码就完工了,如果你想查看一服在线玩家数只需要调用:
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 < PlayerCount def initialize
@serverFirst = ServerFirst.new
end def server_name
"一服"
end def player_count
@serverFirst.online_player_count
end end
这样通过ServerOne的适配,XMLBuilder和ServerFirst之间就成功完成对接了!使用的时候我们甚至无需知道有ServerFirst这个类,只需要正常创建ServerOne的实例就行了。
需要值得注意的一点是,适配器模式不并是那种会让架构变得更合理的模式,更多的时候它只是充当救火队员的角色,帮助解决由于前期架构设计不合理导致的接口不匹配的问题。更好的做法是在设计的时候就尽量把以后可能出现的情况多考虑一些,在这个问题上不要向你的leader学习。
适配器:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
Ruby设计模式透析之 —— 适配器(Adapter)的更多相关文章
- Java设计模式透析之 —— 适配器(Adapter)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9400141 今天一大早,你的leader就匆匆忙忙跑过来找到你:“快,快,紧急任务 ...
- Ruby设计模式透析之 —— 组合(Composite)
转载请注明出处:http://blog.csdn.net/sinyu890807/article/details/9153761 此为Java设计模式透析的拷贝版,专门为Ruby爱好者提供的,不熟悉R ...
- 设计模式C++描述----06.适配器(Adapter)模式
一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...
- Java设计模式透析之 —— 单例(Singleton)
写软件的时候经常需要用到打印日志功能,可以帮助你调试和定位问题,项目上线后还可以帮助你分析数据.但是Java原生带有的System.out.println()方法却很少在真正的项目开发中使用,甚至像f ...
- Headfirst设计模式的C++实现——适配器(Adapter)
duck.h #ifndef _DUCK_H_ #define _DUCK_H_ class DUCK { public: ; ; }; #endif mallard_duck.h #ifndef _ ...
- Java设计模式透析之 —— 策略(Strategy)
今天你的leader兴致冲冲地找到你,希望你能够帮他一个小忙.他如今急着要去开会.要帮什么忙呢?你非常好奇. 他对你说.当前你们项目的数据库中有一张用户信息表.里面存放了非常用户的数据.如今须要完毕一 ...
- Java设计模式透析之 —— 模板方法(Template Method)
今天你还是像往常一样来上班,一如既往地開始了你的编程工作. 项目经理告诉你,今天想在server端添加一个新功能.希望写一个方法.能对Book对象进行处理.将Book对象的全部字段以XML格式进行包装 ...
- Java设计模式透析之 —— 组合(Composite)
听说你们公司最近新推出了一款电子书阅读应用,市场反应很不错,应用里还有图书商城,用户可以在其中随意选购自己喜欢的书籍.你们公司也是对此项目高度重视,加大了投入力度,决定给此应用再增加点功能. 好吧,你 ...
- 设计模式--适配器(Adapter)模式
今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...
随机推荐
- Lambert
Dmap -- 贴图信息 LightColor -- 灯光颜色 KL -- 灯光强度值(开放给美术) EnvColor -- 环境颜色 ka -- 环境光强度 (开放给美术) Dmap * (max ...
- Unity3d在安卓android的更新(APK覆盖)
其实这并没什么技术难点,也不是完美的热更新方案,只能说是退而求其次的一个方法. 起因主要是因为公司几个U3D项目在立项之初都没有能做好热更新的规化,导致现在要去做U3D的热更新非常难,并且项目已处于中 ...
- zoj 3785 What day is that day?
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5272 打表找规律. #include <cstdio> #incl ...
- VS中的预先生成事件和后期生成事件
原文:VS中的预先生成事件和后期生成事件 在C#开发中,有时候需要在程序编译之前或之后做一些操作. 要达到这个目的,可以使用Visual Studio中的预先生成事件和后期生成事件. 下图是一个简单例 ...
- Table Lookup
做OJ的时候,做过类似的,即hash.算法很简单,关键是书上写的和做OJ,是完全不同的风格.有很多值得学习的地方. /* * Table Lookup * 详见<<C程序设计语言>& ...
- 读取Word文档的标题
一:描述,将读取的文档标题添加到下拉框中 二:代码 #region 方法:得到Word文档标题的内容 public static List<string> GetTitles(int j, ...
- doxygen学习笔记
下载doxygen:http://www.cnblogs.com/duxiuxing/p/4301015.html 学习思路 doxygen能够根据代码和注释生成文档.可想而知,doxygen对注释的 ...
- [转]Java Daemon Startup Script
How to start a Java program as a Linux daemon with an /etc/init.d script. See also: http://www.sourc ...
- 《算法实战策略》-chaper19-队列、栈和双端队列
对于计算机专业的学生来说,他们一定会很熟悉一句话:程序设计 = 算法 + 数据结构.而根据笔者的理解,所谓程序设计其实就是为了编程解决实际问题,所谓算法是一种解决问题某种思维的方法,但是思维需要得到编 ...
- c宏的MAX函数
今天从香山上面回来累的跟傻逼一样,回来问了一下胡总的阿里面试的问题.然后其中有一个是宏写max函数.胡总说不好写,然后我就去洗澡了. 洗澡的时候感觉不对啊,回来写了一个: #define MAX(a, ...