设计模式之适配器模式
来源:互联网 发布:气球兵升级数据 编辑:程序博客网 时间:2024/05/21 10:04
对于设计模式,是长期代码的一种优化,我结合一些实例,,以自己的见解讲解一下我的浅识。说到适配器模式,
第一点比较重要的是uml图的理解,也许你现在不理解代码,但是理解了uml图,对于你以后的认识会有很大帮助。
适配器模式主要分为类适配器,对象适配器和缺省适配器。
现在我们看一下类适配器的uml结构图
上面可以看出,适配器模式包括三部分Target(目标),Adaptee(源),Adapter(适配器),在这里的我简单的写下代码,让大家有一个直观的认识
Target
public interface Target { public void operation1();public void operation2();}
Adaptee
public class Adaptee { public void operation1(){System.out.println("我是操作1哦");}}
Adapter
public class Adapter extends Adaptee implements Target{public void operation2() {} }但是从上面我们除了能看到复用了一些代码外,几乎看不到任何别的意思了,这样的感觉很不好,所以现在我们就构造一个经典的场景,
中国的电器工作电压是220v的,而美国的电器工作电压是110v,现在我们在美国买了电器要在中国用,那么怎么办呢?我们需要一个变压器,
因此适配器模式有了另一个名字,变压器模式,或者转换器模式。
那么代码如何进行表示呢?下面给出实例。
中国电压
public class ChinaStandard { public void useCnSta(){System.out.println("我们能使用220V的电压");}}
能使用中国的美国制式电压
public interface AmericaEle { public void useAmSta();}
美国电压
public class AmericaStandard implements AmericaEle{public void useAmSta() {System.out.println("我们只能使用使用110v");}}
变压器
public class Transform extends ChinaStandard implements AmericaEle{ //使用中国220v电压 public void useAmSta() { this.useCnSta(); }}我们通过变压器,能够使用220v的中国电压。哈哈,不难吧。
从上面的场景不难看出我们的适配器模式在于复用代码,(这不废话么),但是我们复用代码的前提是什么呢?
复用代码的前提是在不破坏原有代码的继承结构的基础上,并且不对代码内部的结构进行破坏,也就是我们所说的
为了某个目的,进行暂时性复用某个类的方法,既然是暂时性的,我们不能破坏原来的部分,这个不好理解,我会以jdk的io流为大家
详细介绍为什么。
我们上面的代码对于单一的类能够很好的使用了,但是如果我们的源如果有很多的派生类,但是我们的继承只能继承一个,我们没办法了,
所以我们的对象适配器横空出现了。下面是我们对象适配器的uml:
那么以这个方式,我们对原来的变压器进行优化,就变成了我们的对象适配器变压器
public class Transform implements AmericaEle{ private ChinaStandard chinaStandard=null; public Transform(ChinaStandard chinaStandard){ this.chinaStandard=chinaStandard; } public void useAmSta() { chinaStandard.useCnSta(); }}
从这个代码上我们可以看出,我们只需要定义一个父类,通过构造函数传进去,我们就可以对多个继承关系的源进行适配了。
我们遇到的情况不会像上面一样简单,但是通过变压器的例子我们可以看出,我们的适配器是为了兼容而生的,所以他大多数用的
时候是系统升级的时候,或者要同时使用二个类的功能,而这两个类都有自己的体系,我们破坏将会影响一系列的问题,说了这么多,
意思没有变,那么我们看下复杂的情况。
那么拿我们java io的结构来说吧。我们java io的体系图:
看上去是比较复杂的,也是很让大家头疼的,那么我们一点点的说:
我们的顶级InputStream是一个抽象类,他又自己的流式功能,但是我们的InputStream现在需要一个处理文件的功能,
但是我们处理文件的功能和流式功能是兼容性不好的,也许你会直接说,我们可以直接在InputStream里加入File的处理么?
但是如果贸然加入一些方法,我们在扩展别的功能处理时就会增加InputStream的复杂性,而我们需要的也只是File的一部分功能,
如果继承的话,不仅会破坏原有的体系而且会把我们不用的功能加进来。那么在处理这个问题时,我们用到了适配器模式,
其情况就像下面的图
代码部分:
publicclass FileInputStream extends InputStream{ /* File Descriptor - handle to the open file */ private FileDescriptor fd; private FileChannel channel = null; public FileInputStream(FileDescriptor fdObj) { SecurityManager security = System.getSecurityManager(); if (fdObj == null) { throw new NullPointerException(); } if (security != null) { security.checkRead(fdObj); } fd = fdObj; }}
具体的方式就是用了对象适配器,就像我们有了StringBufferInputStream,但是我们现在需要文件流,必然和StringBufferInputStream不兼容,就跟中国电压和美国电压一样,虽然形式上不完全一样,但是思想上是一样的。StringBufferInputStream和ByteArrayInputStream以及InputStreamReader等等都是用的适配器,因为不知道现有的那个流。
这里我们不详细说了,那么我们看一下缺省适配器,其uml:
缺省适配器在java中的使用比较好的是WindowAdapter,我们怎么理解呢?
看一下代码结构:
public interface WindowListener extends EventListener { public void windowOpened(WindowEvent e); public void windowClosing(WindowEvent e); public void windowClosed(WindowEvent e); public void windowIconified(WindowEvent e); public void windowDeiconified(WindowEvent e); public void windowActivated(WindowEvent e); public void windowDeactivated(WindowEvent e);}如果我们实现WindowListener我们必须写出所有方法,但是我们现在有了WindowAdapter,他是一个抽象类,代码结构
public abstract class WindowAdapter implements WindowListener{ public void windowOpened(WindowEvent e); public void windowClosing(WindowEvent e); public void windowClosed(WindowEvent e); public void windowIconified(WindowEvent e); public void windowDeiconified(WindowEvent e); public void windowActivated(WindowEvent e); public void windowDeactivated(WindowEvent e);}
我只写了部分,但是如果我们实现WindowAdapter,我们就可以只复写自己需要的方法,而不需要把所有的方法都列出来。当然有一点别的好处是。抽象类可以写
默认的实现,而我们的接口不行,而有时候默认的行为是很有用的。
写到这里,本文已经差不多要完了,有很多准备了很久,但是写出来改了又改,我在努力从深一点的方式和大家探讨问题,我相信我会越来越熟练
这种方式。在这里我希望大家把我的错误说出来,代码思想本来就是分享的,为了不误人子弟,有错误一定要和我说,在此献上感谢,笔者和大家都正在这条路上奋斗。
- 设计模式之适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式 之 适配器
- 设计模式 之 适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式之适配器
- 设计模式 之 适配器模式
- 设计模式之适配器模式
- 设计模式之适配器模式
- 设计模式之适配器模式
- 设计模式之适配器模式
- 设计模式之适配器模式
- 设计模式之--适配器模式.
- Netty logo 高性能网络应用框架 Netty
- 5.9.1UI-Label
- 运算符重载
- url地址中的参数存储为对象
- 快速排序(QuickSort)
- 设计模式之适配器模式
- 我的PE了解
- 5.9.2UI-LabelBMFont
- NSString 和 字符串(单纯的字符串内容)有什么区别?
- Eclipse 打开已存在Android工程
- 《剑指Offer》学习笔记--面试题38:数字在排序数组中出现的次数
- VMWare-Windows虚拟机访问宿主Ubuntu共享目录
- 05-13
- 【面试题】-数组A中任意两个相邻元素大小相差1,找出某个数在数组A中的位置。(所有位置 )