一种设计模式:针对接口的适配器模式

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

 近日看了几篇关于java编程技巧方面的文章,其实有时候书上的东西,写的比较的范,博客和论坛是一个学习技术的很好的地方,这一点,安老师在很久以前就跟我们说过。基于切身体会,很多感兴趣的人往往研究的比较深,所以很让阅读者受益匪浅,得到的会比书本上的东西多的多,再说,书本也受篇幅的限制。以下这篇文章是关于java里面的适配器设计模式的讲解,结合例子,清晰易懂。

首先想象这么一个场景,有一天,你的老板交给你这么一个任务,查看你们新上线的游戏中每个服的在线人数。对于相应的功能,相应的接口已经提供,只需要调用就行,例如你们的游戏有三个服务器,只要调用Utility.getOnlinePlayerCount(int),传入相应的数值,就能得到在线人数,如果你传入了一个不存在的服,则会返回-1。然后你只要将得到的数据拼装成XML就好,具体的显示功能由你的老板来完成。于是,初步的代码便很快写出来:

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

图片1

接着定义三个实现了PlayerCount接口的类,分别对应三个不同的服务器:

图片2

图片3

图片4

然后定义一个封装XML的类:XMLBuilder:

图片5

这样,查看一服在线的玩家数为:

图片6

相应的,二服,三服也比较简单,对自己所写的代码,自己也是很满意的。在你提交的时候,你的老板,突然微笑着告诉你,Utility.getOnlinePlayerCount(int)方法主要是针对二、三服的,是后来加上去的,而一服,一直没改过来,是用ServerFirst这个类。

咦,你脑子一动,那只要将Utility.getOnlinePlayerCount(int)方法修改下,将一服加进去就可以了,但是现在问题来了,Utility和ServerFirst这两个类都已经被打到Jar包里了,没法修改啊,咋办呢。分析一下,因为我们前期定义的PlayerCount接口,然后各个实现类的getPlayCount()方法里面,具体的去调用Utility.getOnlinePlayerCount(int)方法,然而,Utility.getOnlinePlayerCount(int)方法并没有实现Utility.getOnlinePlayerCount(1),所以这样不行。对于一服,它自己的获取在线人数的方法是ServerFirst类里面的getOnlinePlayerCount()方法,也就是ServerFirst.getOnlinePlayerCount()方法。

那么我们怎么做呢,很简单,核心思想就是只要能让两个互不兼容的接口能正常对接就行了,上面的代码中,XMLBuilder中使用PlayerCount这个接口来拼装XML,而ServerFirst并没有实现PlayerCount这个接口,所以在XMLBuilder中,就没有办法使用ServerFirst这个类作为参数,并调用其中的获取在线人数的方法,这个时候就需要一个适配器类来为XMLBuilder和ServerFirst之间搭起一座桥梁,把ServerFirst传到PlayerCount中去,便可以调用ServerFirst中的方法了,毫无疑问,ServerOne就将充当适配器类的角色。修改ServerOne的代码,如下所示:

图片7

这样,就可以跟二三服那样使用图片8

来封装相应的XML了。

这也就是适配器模式了,将一个类的接口,转换成用户希望的另一个接口。上文中我们在针对于ServerOne的PlayerCount接口中,使用了ServerFirst,从而实现了我们想要的功能。

学东西,倒不是说学的难就好,其实有时候别人的东西写的好就在于他写的巧,有时间的话,我们可以慢慢欣赏别人的那种巧而焕发出来的美,这其实也是一种赏心悦目的享受。

想看更多的精彩内容,可以关注http://blog.csdn.net/guolin_blog/article/details/9400141

anyShare分享到:
This entry was posted in 新闻动态. Bookmark the permalink.

6 Responses to 一种设计模式:针对接口的适配器模式

  1. 金柳颀 says:

    首先,第一的“写的比较范”,是不是“泛”
    其次,示例中buildXML中 最后,我觉得这个示例有点问题。所谓的适配器模式应该是将原有对象的接口转换为用户希望的接口,因此我们不应该重新实现被适配类的功能,而应该实现一个适配器类,将被适配的类包装起来,所有的功能都应该调用原有的被适配类功能实现,只不过转换一下接口。这个例子也不适合用纯粹的适配器类来解决,因为这会改变原有类的行为,而纯粹的适配器不适于解决这个问题。
    我觉得学习设计模式,首先要彻底理解原有模式提出的背景以及适合解决的问题范围,然后自己的实现根据实际情况有所变动(这是大多数情况)。像这个例子就不是纯粹的适配器可以解决的。

    • 唐敏龙 says:

      柳颀你看得这么仔细,错别字都被揪出来了。关于这个例子应不应该用这样的方法去写,我也没有什么实际的经验,所以我也不好说它的利弊,另外设计模式这个东西本身就不是为了用而想方设法的去用。最下方有个连接是原作者的csdn帖子,关于对适配器模式的理解是否有偏差这一块,你可以给他留言探讨下,我的理解就到这了,正好我也能借此机会跟你们深入学习一下,我这还有他的qq。。

      • 金柳颀 says:

        我看了一下原链接,其实原文下面有评论已经指出这个设计模式并不是适配器的问题了。还有代码里也有缺漏,不知道为什么评论有部分被吞了╮(╯▽╰)╭

  2. 谷敏敏 says:

    适配器模式,Android应用开发中用的很多。

  3. 陈烨 says:

    不错,很有创意。

发表评论