2007-04-24
Adapter - 适配器模式
关键字: 设计模式
意图
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。(GoF)
场景
相信很多人都知道什么是显卡,也有很多人知道显卡的本名——图形适配器。恩,是的,正好这回说说Apater模式,就拿显卡来例子来分析一下Adapter模式。
我们知道显示器(Client)是用来显示图形的,它是不能显示数据,它只能够接受来自图形发送设备Target的信号。可是我们手头上只有CPU(Adaptee)这个产生各种描述图形的数据的数据发送器。我们需要将这些数据让显示器进行显示,可是这两个部件却是不兼容的。于是我们需要一个中间设备,它能够将CPU“适配”于显示器,这便是我们的显卡——图形适配器(Adapter)。
可是我们的CPU(Adaptee)只能输出0/1数据,他是个计算器,而不是图形发送设备(Target)。
这个时候我们的显卡(Adapter)的作用便体现出来了,它负责对CPU进行适配,通过将CPU传过来的数据转换成图形信号,从而将CPU伪装成一个图形发送设备。
这样,我们的电脑的显示流程就变成CPU-显卡-显示器:
上面的这种依赖于对象组合的Adapter模式叫做对象适配器(Object Adapter)。它的特征是继承/实现某一方的类(Target),如这里的图形发送器,同时内部包含一个被适配的类(Adaptee),如这里的CPU。通过重写其父类的方法来进行适配。
另一种的Adapter实现
对于Adapter模式,还有另外一种实现方式,这种适配方式叫做类适配器(Class Adapter)。它与Object Adapter的不同之处在于它继承被适配的对象。
这样的代码在C++中是合法的,但是在Java中规定最多只能继承一个父类,而可以实现多个接口。所以我们需要建立一个IAdaptee的接口,然后将我们的Adapter继承Target同时实现IAdaptee。
对于我们的显示器(Client)方面,Class Adapter跟Object Adapter一样,所以不需要进行修改。
对于Class Adapter,大家也看见了,在Adapter中因为是实现了IAdaptee接口,因此需要实现getData()的接口。一旦Target和IAdaptee拥有相同的方法时,会出现麻烦的。所以尽量优先使用Object Adapter的模式。
小结
作为总结,我觉得显卡本身的定义便很能表达Apater设计模式:“它是主机与显示器之间连接的“桥梁”,作用是控制电脑的图形输出,负责将CPU送来的的影象数据处理成显示器认识的格式,再送到显示器形成图象。”
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。(GoF)
场景
相信很多人都知道什么是显卡,也有很多人知道显卡的本名——图形适配器。恩,是的,正好这回说说Apater模式,就拿显卡来例子来分析一下Adapter模式。
我们知道显示器(Client)是用来显示图形的,它是不能显示数据,它只能够接受来自图形发送设备Target的信号。可是我们手头上只有CPU(Adaptee)这个产生各种描述图形的数据的数据发送器。我们需要将这些数据让显示器进行显示,可是这两个部件却是不兼容的。于是我们需要一个中间设备,它能够将CPU“适配”于显示器,这便是我们的显卡——图形适配器(Adapter)。
java 代码
- // 图形发送设备
- public class Target {
- /**
- * 传送图形信号
- */
- public String request() {
- return "Graphic sender";
- }
- }
java 代码
- // 显示器
- public class Client {
- public static void main(String[] args) {
- Target target = new Targete();
- System.out.println(target.request());
- }
- }
可是我们的CPU(Adaptee)只能输出0/1数据,他是个计算器,而不是图形发送设备(Target)。
java 代码
- // CPU
- public class Adaptee {
- /**
- * CPU输出的数据
- */
- public String getData() {
- return "CPU data";
- }
- }
这个时候我们的显卡(Adapter)的作用便体现出来了,它负责对CPU进行适配,通过将CPU传过来的数据转换成图形信号,从而将CPU伪装成一个图形发送设备。
java 代码
- // 显卡,即我们的适配器
- public class Adapter extends Target {
- // 被代理的设备
- private Adaptee apt = null;
- /**
- * 装入被代理的设备
- */
- public Adapter(Adaptee apt) {
- this.apt = apt;
- }
- /**
- * 被代理的设备传过来的数据转换成为图形输出
- */
- public String request() {
- return apt.getData();
- }
- }
这样,我们的电脑的显示流程就变成CPU-显卡-显示器:
java 代码
- public class Client {
- public static void main(String[] args) {
- // CPU经过显卡的适配后“变”成了图形发送装置了
- Target target = new Adapter(new Adaptee());
- System.out.println(target.request());
- }
- }
上面的这种依赖于对象组合的Adapter模式叫做对象适配器(Object Adapter)。它的特征是继承/实现某一方的类(Target),如这里的图形发送器,同时内部包含一个被适配的类(Adaptee),如这里的CPU。通过重写其父类的方法来进行适配。
另一种的Adapter实现
对于Adapter模式,还有另外一种实现方式,这种适配方式叫做类适配器(Class Adapter)。它与Object Adapter的不同之处在于它继承被适配的对象。
java 代码
- public class Adapter extends Targer, Adaptee {
- ......
- }
这样的代码在C++中是合法的,但是在Java中规定最多只能继承一个父类,而可以实现多个接口。所以我们需要建立一个IAdaptee的接口,然后将我们的Adapter继承Target同时实现IAdaptee。
java 代码
- // IAdaptee接口
- public interface IAdaptee {
- String getData();
- }
java 代码
- // Adaptee 实现IAdaptee
- public class Adaptee implements IAdaptee {
- ......
- }
java 代码
- public class Adapter extends Target implements IAdaptee {
- private IAdaptee apt = null;
- public Adapter(IAdaptee apt) {
- this.apt = apt;
- }
- public String request() {
- return apt.getData();
- }
- public String getData() {
- return apt.getData();
- }
- }
对于我们的显示器(Client)方面,Class Adapter跟Object Adapter一样,所以不需要进行修改。
对于Class Adapter,大家也看见了,在Adapter中因为是实现了IAdaptee接口,因此需要实现getData()的接口。一旦Target和IAdaptee拥有相同的方法时,会出现麻烦的。所以尽量优先使用Object Adapter的模式。
小结
作为总结,我觉得显卡本身的定义便很能表达Apater设计模式:“它是主机与显示器之间连接的“桥梁”,作用是控制电脑的图形输出,负责将CPU送来的的影象数据处理成显示器认识的格式,再送到显示器形成图象。”
评论
qqwjz
2007-07-09
个人认为Adaptee ,Target 是相对的,要看你原来的主程序使用的是哪个接口。一般把程序中使用的那个接口作为Target。
glassesbamboo
2007-06-11
为什么不用:
实现呢?
public class Adapter extends Adaptee implements ITarget {
.......
}
实现呢?
liuganquan
2007-05-22
呵呵,都是初级会员
那要看什么情况拉
最好少用继承,除非确定基类变化小,并且子类通用代码多的情况
javastudy 写道
liuganquan 写道
优先使用组合 而不是继承 ,所以object adapter要优于class adapter~~~
那要看什么情况拉
最好少用继承,除非确定基类变化小,并且子类通用代码多的情况
lintomny
2007-04-25
liuganquan 写道
优先使用组合 而不是继承 ,所以object adapter要优于class adapter~~~
正如你所说的Object Adapter要优于Class Adapter,我的笔记里没有记录Class Adapter。你不说我还忘了补充Class Adapter的内容呢。呵呵。
原文补充上了这方面的内容了。
lintomny
2007-04-25
daynight830 写道
其实把适配器比作笔记本的变压器更为合适。
或许你这么说也可以,通过电源适配器将不合适的电源转换成笔记本能够正常工作的电压。
适配器的作用就是将不合适不兼容的两个部件,通过一定的处理转换达到兼容。
刚想到我笔记本上有一个六合一读卡适配器。呵呵!:D
liuganquan
2007-04-24
优先使用组合 而不是继承 ,所以object adapter要优于class adapter~~~
daynight830
2007-04-24
其实把适配器比作笔记本的变压器更为合适。
- 浏览: 28377 次
- 性别:

- 来自: 广州

- 详细资料
搜索本博客
最新评论
-
Visitor - 访问者模式
楼主大哥的这个vistor模式,小弟偶曾在工商银行取钱时就是这样的,呵呵,更加深 ...
-- by h_yz -
Visitor - 访问者模式
受教了,真的很不错。
-- by wjh0205 -
Visitor - 访问者模式
有一点没说:访问者模式一般用在数据结构稳定的情况下。银行这个例子不是很合适,因为 ...
-- by 渐行渐远 -
Visitor - 访问者模式
lintomny 写道 话说有一个银行,有三个窗口,但是每个窗口的智能都是 ...
-- by farryu -
Visitor - 访问者模式
解释的不错,不过可能稍有点不够详细。
-- by zhangcheng






评论排行榜