首页 理论教育 适配器模式:面向对象程序设计中的新增同学

适配器模式:面向对象程序设计中的新增同学

时间:2023-11-03 理论教育 版权反馈
【摘要】:第三章我们班来了位新同学——适配器模式3.1我们班来了位新同学——适配器模式时间:12月15日地点:教室人物:06信管全班同学大二上学期的一天……就好比我们讲的适配器。

适配器模式:面向对象程序设计中的新增同学

第三章 我们班来了位新同学——适配器模式

3.1 我们班来了位新同学——适配器模式

时间:12月15日  地点:教室  人物:06信管全班同学

大二上学期的一天……

早上到教室,依然是在响铃前3分钟。今天是上那讨厌的汇编,学了我大半个学期,到现在还不会编。看来今天这个节我又得晕呼着过去了。

正在我叹气的时候,教室里出现了骚动,还有好多人在窃窃私语哩。不少男生还吹起了口哨。怪了,今天有啥好事哩?正在我嘀咕的时候,班主任进来了,教室门口走进来一位美女?嘿嘿……还是金发的!

不等我回神,班主任来了:“同学们,借大家上课前几分钟的时间,给大家说个事。今天,我们班来了位新同学,以后她会和大家一起学习。Anne,来,给大家做个自我介绍。”

台下一片骚动……

只见坐在我前面的金发MM站起来了。非常有礼貌地说

“Good morning everyone, My name is Anne, I am from Canada, please take care of!”

妈呀,英语?头晕……

只见她甜甜地笑着,我正晕呼,她接着说:“大家早上好,我叫Anne,我来自加拿大,请多关照!”

这回可听懂了,人家叫安妮哩!人漂亮名字也好听,这回可得迷倒我们班男生了。也难怪,在我理工院校,女生少之又少,这回突然来了位金发MM,我们班男生可有福了。不过那个MM也真是的,都会中文,为啥来个英语啊!

看来接下来我们的大学生活就热闹了……

3.2 适配器模式

时间:12月16日  地点:大B房间  人物:大B,小A

都说学好普通话,走遍中国都不怕。就好像Anne来到我们班,如果说她只会说英文,那我们好大一部份同学都不一定听得懂。可是她还会说中文,那以后和大家在一起沟通就好多了。就好比我们讲的适配器。

大B:“师弟,你知道怎样是适配器模式吗?”

小A:“就是把一个类的借口转换成客户端所期待的另一种接口,从而使原接口不匹配而无法在一起工作的两个类能在一起工作。”

大B:“从功能上讲这些接口不兼容的类一般具有相同或相似的功能。通常我们通过修改该类的接口来解决这种接口不兼容的情形,但是如果我们不愿意为了一个应用而修改各原有的接口,或者我们压根就没有原有对象的源代码那该怎么办呢?此时Adapter模式就会派上大用场了。你能不能用代码来实现呐?”

小A:“好。我试一下。”

如果有两个编译好的(无源代码)类,类A有某些功能,但是需要一个xml读取模块才能工作,

这个模块要实现这个接口:

你的另一个类B恰好有这个功能,但是B实现的是这个接口:

这个时候我们的做法是写个适配器:

这个就是适配器模式了。

适配器模式还有另外一种实现方式:

大B:“对,没错!上次有个朋友从美国给我带回一个微波炉,但因为美国的生活用电电压是110V,而中国的电压是220V,所以我不能使用,幸好朋友有先见之明,给我带回一个变压器,能把220V电压转换成110V电压,我才可以放心使用了。”

小A:“嘿嘿!师兄你那位朋友还挺有心的嘛!一定是位很要好的朋友吧?”

大B:“还不就是那个大学时候的死党老E,那鸟人大学毕业后一直在国外,听说最近要回来一趟哩!”

小A:“是吗?那到时你们可爽了,又可以一起喝酒啦!”

大B:“嘿嘿!是啊!毕业几年一直没见过那鸟人,跑国外喝了几年养墨水,回来一定得好好宰他一顿。”

小A:“那是要的啦!”

大B:“对了,你编程学得不错,能不能把刚才我说的,也就是微波炉电压转换用代码表示?”

小A:“好。通过适配,使c220类能在c110类中使用。”

程序代码:

运行结果:

220v电压!

经变压器转换成

110v电压

大B:“吼!非常不错喔!”

3.3 适配器模式的几个要素

大B:“那适配器模式有几个要素?”

小A:“我道还没有注意,给我说说适配器模式所涉及的角色有哪些吧!”

大B:“适配器模式所涉及的角色包括:目标、客户、被适配者、适配器。”

小A:“那这些要素主要都做些什么?”

大B:“目标(CTarget):定义一个客户端使用的特定接口。客户(CClient):使用目标接口,与和目标接口一致的对象合作。被适配者(CAdaptee):一个现存需要匹配的接口。适配器(CAdapter):负责将CAdaptee的接口转换成CTarget的接口。适配器是一个具体的类,这是本模式的核心。由此可见,但客户端调用Adapter接口时候,Adapter便会调用Adaptee的操作相应请求,该模式就完成了接口的适配过程。”

3.4 优势和缺陷

小A:“那适配器模式好在哪里?它又有什么缺陷呐?给我讲讲吧?”

大B:“适配器模式可以将一个类的接口和另一个类的接口匹配起来,使用的前提是你不能或不想修改原来的适配器母接口。例如,你向第三方购买了一些类、控件,但没有源程序,这时,使用适配器模式,你可以统一对象访问接口,但客户调用可能需要变动。”

3.5 何时使用适配器模式

小A:“使用一个已经存在的类,如果它的接口,方法和你的要求不相同的时候,可以考虑用适配器模式吗?”

大B:“可以啊!如果两个类所做的事情相同或相似,但是他们有不同的接口的时候要使用它。类都是共享同一个接口,那你想客户代码要怎么样才行?”

小A:“客户代码只要统一调用同一接口就行了,是不是这样简单,直接,更紧凑?”

大B:“是的,软件都是需要维护的,维扩可能会因不同的开发人员,不同的产品,不同的厂家,造成功能类似但是接口不同,这时就可以使用适配器。”(www.xing528.com)

小A:“你是说,在软件开发后期或维护的时候再考虑使用适配器?”

大B:“在设计阶段没必要把类似的功能类的接口设计的不同。”

小A:“可是不同的程序员定义方法的名称也可能是不同的呀!”

大B:“那也是,但是在一般公司内部,类和方法的命名是有规范的,做好前期就设计,接口不相同的时候,第一时间不应该考虑用适配器,而是考虑通过重构统一接口。”

小A:“也就是说要在双方都不太容易修改的时候,这个时候再使用适配器模式适配?不是一出现不同时就使用它?会不会有在设计初就考虑用适配器模式的情况哩?”

大B:“有,就好像在设计一个系统时使用第三方开发组件,这个组件的接口与系统接口不相同,这个时候就不用为了迎合它去改动自己的接口,在这种情况下,虽然是在开发设计阶段,解决接口不同的问题也可以用适配器模式。”

小A:“这样呐!”

大B:“有人举过这样一个例子:虎与飞禽是没有直接关联的两类动物,但是现在出来了个“飞虎”,它同时具有虎肉食动物跟飞禽会飞的特质,要在飞禽这个类系中添加一个成员类“飞虎”,除了直接实现“飞虎”类,还有一种简单的办法是实现一个Adapter类,在其中包容一个虎的对象,同时实现飞禽的接口即可。当然,对于这个问题,多继承或者实现多接口可能是一个更直观的作法,在实际应用中,可视具体需要确定采用何种作法。”

3.6 适配器总体上可以分为哪两类

小A:“适配器还要有类别之分的吗?

大B:“是啊,根据重用使用方式的不同一般将适配器模式分为两类。”

小A:“喔。是吗?哪两类哩?”

大B:“类适配器和对象适配器。”

3.7 类适配器 VS 对象适配器

大B:“我还是跟你讲讲类适配器和对象适配器吧!举些例子,这样你就明白了。”

小A:“好!”

大B:“要正确地区别这两种适配器的区别,我们还是从一个简单的例子开始吧!我们的系统中有一个具有某个特定功能的类Adaptee,一个客户类Client――他需要一个实现Target接口的对象,和一个Target接口。”以下是他们的源码

“根据上一小节的分析我们知道此时需要一个Adapter对象,该对象实现Target接口,同时他又重用现有的Adaptee类。任何有一点点OO(面向对象)知识的人都会想到通过继承可以达到重用的目的。”

下面是通过继承实现Adaptee类重用的例子:

大B:“看,简单明了吧!现在的过程就是:客户调用Target接口的request方法,实际就是调用其父类Adaptee的specialRequest方法。”

小A:“嘿嘿!这样一说倒真的是简单喔!”

大B:“对啊!这就是大家通常常说的类的适配器!类适配器具有以下的两个特点:1、适配器类(Adapter)实现Target接口;2、适配器类(Adapter)通过继承来实现对Adaptee类的重用。”

下面是一个通过组合关系实现继承的例子,以下是源码:

对于这两者不同的适配器客户代码其实是完全一样的。以下是客户的代码:

大B:“现在可是全明白了吧?”

小A:“嘿嘿!现在都懂了。”

3.8 类适配器和对象适配器的哪些不同?

小A:“那类适配器和对象适配器有哪些不同哩?”

大B:“类适配器是通过继承类适配者类(Adaptee Class)实现的,另外类适配器实现客户类所需要的接口。当客户对象调用适配器类方法的时候,适配器内部调用它所继承的适配者的方法。对象适配器包含一个适配器者的引用(reference),与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。”

3.9 日常生活中的适配器

大B:“适配器的例子在日常生活中随处可见。”

小A:“喔?”

大B:“新的电脑鼠标一般都是USB接口,而旧的电脑机箱上根本就没有USB接口,而只有一个PS2接口,这时就必须有一个PS2转USB的适配器,将PS2接口适配为USB接口。一般家庭中电源插座有的是两个孔(两项式)的,也有三个孔(三项式)的。很多时候我们可能更多地使用三个引脚的插头,但是那种两孔的插座就不能满足我们的需求,此时我们一般会买一个拖线板,该拖线板的插头是是两脚插头,这样就可以插入原先的两孔插座,同时拖线板上带有很多两孔、三孔的插座!这样不仅可以扩容,更主要的是将两孔的插座转变为三孔的插座!”

小A:“嘿嘿!仔细想来好像是有好多适配器的例子喔!”

大B:“设计模式里的适配器模式和日常生活中的适配器的作用是完全一样的。”

3.10 电脑电源适配器

小A想去电脑城买个笔记本电脑电源适配器,这天他来找师兄先了解一些关于电脑电源适配器。

小A:“师兄,什么样的是笔记本电脑的电源适配器?”

大B:“多数笔记本电脑的电源适配器可以自动检测100~240V交流电(50/60Hz)。基本上所有的笔记本电脑都把电源外置,用一条线和主机连接,这样可以缩小主机的体积和重量,只有极少数的机型把电源内置在主机内。在电源适配器上都有一个铭牌,上面标示着功率,输入输出电压和电流量等指标,特别要注意输入电压的范围,这就是所谓的‘旅行电源适配器’,如果到市电电压只有100V的国家时,这个特性就很有用了,有些水货笔记本电脑是只在原产地销售的,没有这种设计,甚至只有100V的单一输入电压,在我国的220V市电电压下插上就会烧毁。”

小A:“电源适配器?”

大B:“嗯,对。电源适配器是小型便携式电子设备及电子电器的供电电源变换设备,一般由外壳、电源变压器和整流电路组成,按其输出类型可分为交流输出型和直流输出型;按连接方式可分为插墙式和桌面式。广泛配套于电话子母机、游戏机语言复读机、随身听、笔记本计算机、蜂窝电话等设备中。”

小A:“师兄,手提电脑电源适配器要怎么买才好啊?”

大B:“呵呵!这样说起来要注意的问题就多了喔!”

小A:“是么?那电源适配器的标称电压和电流是什么意思啊?”

大B:“首先,一般电源适配器(以下简称电源)标称的电压,是指开路输出的电压,也就是外面不接任何负载,没有电流输出时候的电压,所以也可以理解为,此电压就是电源输出电压的上限。对于电源内部使用了主动稳压的元件的情况下,即使市电电压有所波动,其输出也是恒定值,象市面上一般的小变压器,比如随身听之类配的电源,如果市电波动,该电源的输出也会随之波动的。一般来讲普通电源适配器的真正空载电压也不一定和标称电压完全一致,因为电子元件的特性不可能完全一致,所以有一定的误差,误差越小,对电子元件的一致性要求越高,生产的成本就高了,所以价格也就贵一些了。另外,关于标称的电流值,无论任何电源都有一定的内阻,因此当电源输出电流的时候,会在内部产生压降,导致两件事情,一个是产生热量,所以电源会热,另一个是导致输出电压降低,相当于内部消耗。”

小A:“那都是同样标称电压的电源,输出电流不同,能不能用在同一台本本上?”

大B:“电源电压一样,输出电流不同,能不能用在同一台本本上。基本的原则是大标称电流的电源可以代替小标称电流的电源。估计有人会这样想,觉得大标称电流的电源会烧坏本本,因为电流大了嘛。实际上电流多大在电压相同的情况下取决于负载,当本本高负荷运转的时候,电流大些,本本进入待机的时候,电流就小些,大标称电流的电源有足够的电流余量。反之,有人用56w的电源代替72w的用起来也没什么问题,原因是通常电源适配器的设计留有一定的余量,负载功率都要小于电源功率,所以这种代替在一般使用上是可行的,但是剩余的电源功率余量就很少了,一旦你的本本接了很多外设,比如两块usb硬盘,然后cpu全速运转,再有一个底座,上面来个光驱全速读盘,再加上同时给电池充电,估计就危险了,要随时用手摸摸你的电源是不是已经可以煮鸡蛋了。所以最好不要用小电流电源代替大电流电源。”

小A:“师兄呐,为什么一模一样的机器,别人的电源温温的,我的总是很烫?”

大B:“先不要怀疑你的电源有问题,先看看你的本本在干什么,是不是像上面说的两块USB硬盘,CPU全速运转,硬盘疯狂读写,光驱全速读盘,同时给电池充电,大声放着音乐,屏幕亮度最大,无线网卡一直在侦测信号等等,善用电源管理,根据任务合理调整本本的工作状态是很重要的。”

小A:“那电源标称电压比我的本本电池电压高很多,不会出事吧?”

大B:“首先,要知道的是,电源给本本供电与电池给本本供电是不同的。电池供电,电池的输出是纯直流,干净得很,电池的电压既不可能也不需要设计得很高,锂电池化学特性决定了一节电芯的输出电压只能在3.6V左右,所以很多电池都是采用三级串联的方式,10.8V也就成了很流行的电池电压。有些电池的标称值比3.6V的整数倍稍大一些,比如3.7V或者11.2V等等,其实是为了保护电池。电源供电,情况就复杂一些,首先需要对加入电压进行进一步的稳压滤波,以保证在电源性能不很好的情况下稳定工作,稳压后的电压分城两个部分,一路给本本工作供电,另一路给电池充电,给本本供电的那部分同电池供电的时候相同,而给电池充电的那部分需要通过电池的充电控制电路才可以加在电芯上,控制电路可以很复杂,所以电源电压必须大于电芯电压才有充分的能力供应给充电控制电路的各单元。最后真正加到电芯上的电压决不会是你的电源标称的电压。放心好了。另外搜索了一下,大家看看电池的充电控制电路包括些什么东西,应该包括初级稳压、精密可调谐稳压、可控硅调节脉动输出、稳压输出、电流反馈、芯片充电过程记录与运算、充电程序自反馈调节参数等等,呵呵,是不是感觉还是很需要消耗一部分电能的啊。”

小A:“为什么理论上原配的电源通常比非原配的电源要好?”

大B:“理论上来说。原装的电源肯定好一些,但是,实际使用可能感觉不到差别。通常我们的设备都有一个电压输入的安全范围,比如一个2.5的移动硬盘,它是要求5V加减5%,过高或者过低,保护电路会停止设备的工作。如果保护电路启动,那说明在这之前,你的机器已经接近或者超过了它设计所能承受的上限或者下限,这对机器的寿命都是有影响的。(当然,这里提到的非原装电源,还是做工好的,劣质产品,就不要提了。)更重要的问题可能是本本的数据安全,突然的自动保护而停止工作对于计算机来说是很恐怖的事情,尤其是很多不用电池的朋友。有的时候计算机莫名其妙的重新启动也和此有关。对于原装的电源来说,厂家很清楚自己的电源需要有多大的负载能力,计算出来的安全的标称电压电流肯定准确的多。然而如果使用的是非原配适配器,比如通用型的变压器之类,上述问题不能得到认真考虑,这是用户就只能从电源参数上尽量想办法获得兼容,但是每种适配器的内阻是不同的,标称电压的允许误差可能不同,标称电流输出下电压的变化范围的也可能有所不同,如果你不是仔细测量了相关数值,肯定,是有风险的。这就是原装与非原装的区别,这里可没说到劣质电源啊,这样的货色,肯定是更不保险的。”

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈