适配器模式
来源:互联网 发布:ncbi下载基因组数据 编辑:程序博客网 时间:2024/06/11 19:39
适配器模式
在《HeadFirst设计模式》一书中是这么来解释适配器模式的:将一个类的接口,转换成客户期望的另一个接口。适配器让原来的接口不兼容的类可以合作无间。
现在有一个场景:现在已经有一个软件系统,为了使得这个软件系统更加强大,需要和另外一个厂商类库进行配合使用,由于两者又不兼容,那么该怎么办呢?
我们可以采取下面的方式,在这个软件系统和厂商类库之间创建一个适配器,让两者可以协同工作,在此,我们先不管这个适配器是如何创建的!
先来一个不太恰当的例子但是容易理解,假设一个boss不知道鸡是什么,他只知道鸡可以飞,可以咯咯的叫,别的什么不知道。现在他对一个养殖老板说要100只鸡,但是呢养殖老板只有50只鸡,所以老板决定搞一些鸭子来糊弄一下这个不能区分鸡鸭的boss.好啦,先来定义两个接口:鸡、鸭。还要两个实现类,野鸡,野鸭!
鸡、鸭接口:
interface Chook {/** * 鸡能咯咯叫 */public void gege();/** * 鸡能飞 */public void fly();}
interface Duck {/** * 鸭是嘎嘎叫 */public void gaga();/** * 鸭能飞 */public void fly();}两个实现类,野鸡,野鸭:
public class YeChook implements Chook{@Overridepublic void gege() {System.out.println("咯咯叫");}@Overridepublic void fly() {System.out.println("鸡飞");}}
public class YeDuck implements Duck{@Overridepublic void gaga() {System.out.println("嘎嘎叫");}@Overridepublic void fly() {System.out.println("鸭子飞");}}
要想用鸭来冒充鸡,还要一个适配器
public class ChookDuckAdapter implements Chook{private Duck duck;public ChookDuckAdapter(Duck duck) {this.duck = duck;}@Overridepublic void gege() {duck.gaga();}@Overridepublic void fly() {// TODO 自动生成的方法存根}}
public class Test {public static void main(String[] args) {//先来50只鸡for (int i = 0; i < 5; i++) {Chook chook=new YeChook();chook.gege();chook.fly();}//先来50只用鸭子来冒充的假鸡for (int i = 0; i < 5; i++) {Duck duck=new YeDuck();//把鸭子包装成了鸡Chook chookDuck=new ChookDuckAdapter(duck);//调用这个假鸡的方法,实际上还是掉用的鸭chookDuck.gege();chookDuck.fly();}}}
适配器的工作流程如下:
首先,客户通过目标接口调用适配器的方法对适配器发出请求;
然后,适配器使用被适配者接口把请求转换成被适配者的一个或者多个调用接口;
最后,客户收到调用的结果,但并未察觉这一切是适配器在器转换作用。
我们再看一个例子:
早期的集合类型(例如:Vector,Stack,Hashtable)都实现了一个名为elements的方法,该方法会返回一个枚举(Enumeration),但是随着JDK的升级,更新集合类时,开始使用了Iterator的接口,这个接口和枚举接口很像,都可以让你遍历集合类型内的每个元素,但是不同的是,迭代器还是提供了删除元素的方法;而今天经常面对遗留代码,这些遗留代码暴露出枚举接口,但是我们又希望在新的代码中只是用迭代器。想解决这个问题,看来我们需要构造一个适配器。
interface Enumeration<E> {/** * @return 枚举中是否有下一个元素 */public boolean hasMoreElements();/** * @return 返回此枚举的下一个元素 */public E nextElement();}
interface Iterator<T> {/** * @return 集合中是否有下一个元素 */public boolean hasNext();/** * @return 返回集合中的元素 */public T next();/** * 移除集合中最后一个元素 */public void remove();}
public class EnumerationIterator<T> implements Iterator<T> {private Enumeration<T> mEnumeration;public EnumerationIterator(Enumeration<T> mEnumeration) {this.mEnumeration = mEnumeration;}@Overridepublic boolean hasNext() {return mEnumeration.hasMoreElements();}@Overridepublic T next() {return mEnumeration.nextElement();}@Overridepublic void remove() {System.out.println("枚举不能移除,我们也可以抛出一个异常!");}}
其实适配器主要有两种,一种是对象适配器,一种是类适配器类适配器需要多重继承才能实现它,这在JAVA中是不可能的。对象适配器利用组合方式将请求传送给适配者。所以对象适配器和类适配器使用两种不同的适配方法(分别是组合与继承),这两种实现究竟有什么差异呢?
在上图中可以看出,Adaptee类并没有sampleOperation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,提供一个中间环节,即类Adapter,把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是继承关系,这决定了这个适配器模式是类的:
从上图可以看出,Adaptee类并没有sampleOperation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
好啦,不写了!。。。。
- 适配器及适配器模式
- 适配器及适配器模式
- 适配器模式(类适配器)
- 适配器模式(默认适配器)
- 适配器模式(对象适配器)
- 适配器模式-类适配器
- 适配器模式-对象适配器
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- 适配器模式
- Picked up JAVA_TOOL_OPTIONS: -javaagent:/usr/share/java/jayatanaag.jar
- UVA - 10305 - Ordering Tasks(拓扑排序)
- 黑马程序员——OC笔记之内存管理
- 使用druid连接池,配置sql防火墙发现的sql注入问题
- 二叉树的层次非递归遍历运用队列
- 适配器模式
- Rotate List
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第一节:3D时代来临!
- Linux chmod +755和chmod +777 各是什么意思呢?
- /dev/mem可没那么简单
- HTML 相对路径表示方法
- 设置应用程序的图标(Setting the Application Icon)— Mac OS X
- SDN开源,从你的全世界路过
- 系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式