为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

JAVA装饰器模式详解

2019-09-19 9页 doc 26KB 20阅读

用户头像

is_531654

暂无简介

举报
JAVA装饰器模式详解LZ到目前已经写了九个设计模式,回过去看看,貌似写的有点凌乱,LZ后面会尽量改进。 那么本章LZ和各位读友讨论一个与JAVA中IO有着不解情缘的设计模式,装饰器模式。 定义:装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 这一个解释,引自百度百科,我们注意其中的几点。 1,不改变原类文件。 2,不使用继承。 3,动态扩展。 上述三句话一语道出了装饰器模式的特点,下面LZ给出装饰器模式的类图,先上图再解释。 从图中可以看到,我们装饰的是一个接口...
JAVA装饰器模式详解
LZ到目前已经写了九个设计模式,回过去看看,貌似写的有点凌乱,LZ后面会尽量改进。 那么本章LZ和各位读友讨论一个与JAVA中IO有着不解情缘的设计模式,装饰器模式。 定义:装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 这一个解释,引自百度百科,我们注意其中的几点。 1,不改变原类文件。 2,不使用继承。 3,动态扩展。 上述三句话一语道出了装饰器模式的特点,下面LZ给出装饰器模式的类图,先上图再解释。 从图中可以看到,我们装饰的是一个接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰。 另外,这个类图只是装饰器模式的完整结构,但其实里面有很多可以变化的地方,LZ给出如下两条。 1,Component接口可以是接口也可以是抽象类,甚至是一个普通的父类(这个强烈不推荐,普通的类作为继承体系的超级父类不易于维护)。 2,装饰器的抽象父类Decorator并不是必须的。 那么我们将上述标准的装饰器模式,用我们熟悉的JAVA代码给诠释一下。首先是待装饰的接口Component。 packagecom.decorator; publicinterfaceComponent{ voidmethod(); } 接下来便是我们的一个具体的接口实现类,也就是俗称的原始对象,或者说待装饰对象。 packagecom.decorator; publicclassConcreteComponentimplementsComponent{ publicvoidmethod(){ System.out.println("原来的方法"); } } 下面便是我们的抽象装饰器父类,它主要是为装饰器定义了我们需要装饰的目标是什么,并对Component进行了基础的装饰。 packagecom.decorator; publicabstractclassDecoratorimplementsComponent{ protectedComponentcomponent; publicDecorator(Componentcomponent){ super(); this.component=component; } publicvoidmethod(){ component.method(); } } 再来便是我们具体的装饰器A和装饰器B。 packagecom.decorator; publicclassConcreteDecoratorAextendsDecorator{ publicConcreteDecoratorA(Componentcomponent){ super(component); } publicvoidmethodA(){ System.out.println("被装饰器A扩展的功能"); } publicvoidmethod(){ System.out.println("针对该方法加一层A包装"); super.method(); System.out.println("A包装结束"); } } packagecom.decorator; publicclassConcreteDecoratorBextendsDecorator{ publicConcreteDecoratorB(Componentcomponent){ super(component); } publicvoidmethodB(){ System.out.println("被装饰器B扩展的功能"); } publicvoidmethod(){ System.out.println("针对该方法加一层B包装"); super.method(); System.out.println("B包装结束"); } } 下面给出我们的测试类。我们针对多种情况进行包装。 packagecom.decorator; publicclassMain{ publicstaticvoidmain(String[]args){ Componentcomponent=newConcreteComponent();//原来的对象 System.out.println("------------------------------"); component.method();//原来的方法 ConcreteDecoratorAconcreteDecoratorA=newConcreteDecoratorA(component);//装饰成A System.out.println("------------------------------"); concreteDecoratorA.method(缪买网 www.miumai.com);//原来的方法 concreteDecoratorA.methodA();//装饰成A以后新增的方法 ConcreteDecoratorBconcreteDecoratorB=newConcreteDecoratorB(component);//装饰成B System.out.println("------------------------------"); concreteDecoratorB.method();//原来的方法 concreteDecoratorB.methodB();//装饰成B以后新增的方法 concreteDecoratorB=newConcreteDecoratorB(concreteDecoratorA);//装饰成A以后再装饰成B System.out.println("------------------------------"); concreteDecoratorB.method();//原来的方法 concreteDecoratorB.methodB();//装饰成B以后新增的方法 } } 下面看下我们运行的结果,到底是产生了什么效果。 从此可以看到,我们首先是使用的原始的类的方法,然后分别让A和B装饰完以后再调用,最后我们将两个装饰器一起使用,再调用该接口定义的方法。 上述当中,我们分别对待装饰类进行了原方法的装饰和新功能的增加,methodA和methodB就是新增加的功能,这些都是装饰器可以做的,当然两者并不一定兼有,但一般至少会有一种,否则也就失去了装饰的意义。 另外,文章开篇就说道了IO与装饰器的情缘,相信各位就算不太清楚,也都大致听说过JAVA的IO是装饰器模式实现的,所以LZ也不再废话,在给出一个标准的模板示例以后,直接拿出IO的示例,我们真枪实弹的来。 下面LZ直接给出IO包中的部分装饰过程,上面LZ加了详细的注释以及各个装饰器的功能演示,各位可以和上面标准的装饰器模式对比一下,LZ不得不感叹,IO与装饰器的孽缘。 packagecom.decorator; importjava.io.BufferedinputStream; importjava.io.BufferedReader; importjava.io.DataInputStream; importjava.io.FileInputStream; importjava.io.IOException; importjava.io.InputStream; importjava.io.InputStreamReader; importjava.io.LineNumberReader; importjava.io.PushbackInputStream; importjava.io.PushbackReader; publicclassIOTest{ /*test.txt内容: *helloworld! */ publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{ //文件路径可自行更换 finalStringfilePath="E:/myeclipseproject/POITest/src/com/decorator/test.txt"; //inputStream相当于被装饰的接口或者抽象类,FileInputStream相当于原始的待装饰的对象,FileInputStream无法装饰InputStream //另外FileInputStream是以只读方式打开了一个文件,并打开了一个文件的句柄存放在FileDescriptor对象的handle属性 //所以下面有关回退和重新标记等操作,都是在堆中建立缓冲区所造成的假象,并不是真正的文件流在回退或者重新标记 InputStreaminputStream=newFileInputStream(filePath); finalintlen=inputStream.available();//记录一下流的长度 System.out.println("FileInputStream不支持mark和reset:"+inputStream.markSupported()); System.out.println("---------------------------------------------------------------------------------"); /*下面分别展示三种装饰器的作用BufferedInputStream,DataInputStream,PushbackInputStream,LZ下面做了三个装饰器的功能演示*/ //首先装饰成BufferedInputStream,它提供我们mark,reset的功能 BufferedInputStreambufferedInputStream=newBufferedInputStream(inputStream);//装饰成BufferedInputStream System.out.println("BufferedInputStream支持mark和reset:"+bufferedInputStream.markSupported());
/
本文档为【JAVA装饰器模式详解】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索