首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

研磨设计方式之装饰模式-3(转)

2012-09-27 
研磨设计模式之装饰模式-3(转)3? 模式讲解3.1? 认识装饰模式(1)模式功能??????? 装饰模式能够实现动态的为

研磨设计模式之装饰模式-3(转)

3? 模式讲解3.1? 认识装饰模式

(1)模式功能
??????? 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象增加功能,相当于是改变了对象的外观。当装饰过后,从外部使用系统的角度看,就不再是使用原始的那个对象了,而是使用被一系列的装饰器装饰过后的对象。
??????? 这样就能够灵活的改变一个对象的功能,只要动态组合的装饰器发生了改变,那么最终所得到的对象的功能也就发生了改变。
??????? 变相的还得到了另外一个好处,那就是装饰器功能的复用,可以给一个对象多次增加同一个装饰器,也可以用同一个装饰器装饰不同的对象。


(2)对象组合
??????? 前面已经讲到了,一个类的功能的扩展方式,可以是继承,也可以是功能更强大、更灵活的对象组合的方式。
??????? 其实,现在在面向对象设计中,有一条很基本的规则就是“尽量使用对象组合,而不是对象继承”来扩展和复用功能。装饰模式的思考起点就是这个规则,可能有些朋友还不太熟悉什么是“对象组合”,下面介绍一下“对象组合”。
什么是对象组合
??????? 直接举例来说吧,假若有一个对象A,实现了一个a1的方法,而C1对象想要来扩展A的功能,给它增加一个c11的方法,那么一个方案是继承,A对象示例代码如下:


??????????????????????? ?图4? Java的I/O的InputStream部分对象层次图

?


?查看上图会发现,它的结构和装饰模式的结构几乎是一样的:

InputStream就相当于装饰模式中的Component。其实FileInputStream、ObjectInputStream、StringBufferInputStream这几个对象是直接继承了InputSream,还有几个直接继承InputStream的对象,比如:ByteArrayInputStream、PipedInputStream等。这些对象相当于装饰模式中的ConcreteComponent,是可以被装饰器装饰的对象。那么FilterInputStream就相当于装饰模式中的Decorator,而它的子类DataInputStream、BufferedInputStream、LineNumberInputStream和PushbackInputStream就相当于装饰模式中的ConcreteDecorator了。另外FilterInputStream和它的子类对象的构造器,都是传入组件InputStream类型,这样就完全符合前面讲述的装饰器的结构了。

?????? ?同样的,输出流部分也类似,就不去赘述了。
?????? ?既然I/O流部分是采用装饰模式实现的,也就是说,如果我们想要添加新的功能的话,只需要实现新的装饰器,然后在使用的时候,组合进去就可以了,也就是说,我们可以自定义一个装饰器,然后和JDK中已有的流的装饰器一起使用。能行吗?试试看吧,前面是按照输入流来讲述的,下面的示例按照输出流来做,顺便体会一下Java的输入流和输出流在结构上的相似性。


2:自己实现的I/O流的装饰器——第一版
??????? 来个功能简单点的,实现把英文加密存放吧,也谈不上什么加密算法,就是把英文字母向后移动两个位置,比如:a变成c,b变成d,以此类推,最后的y变成a,z就变成b,而且为了简单,只处理小写的,够简单的吧。
??????? 好了,还是看看实现简单的加密的代码实现吧,示例代码如下:

?

?

public class EncryptOutputStream2? extends FilterOutputStream{

??? private OutputStream os = null;

??? public EncryptOutputStream2(OutputStream os){

?????? //调用父类的构造方法

?????? super(os);

??? }

??? public void write(int a) throws IOException {

?????? //先统一向后移动两位

?????? a = a+2;

?????? //97是小写的a的码值

?????? if(a >= (97+26)){

?????????? //如果大于,表示已经是y或者z了,减去26就回到a或者b了

?????????? a = a-26;

?????? }

?????? //调用父类的方法

?????? super.write(a);

??? }

}

?

再测试看看,是不是跟其它的装饰器一样,可以随便换位了呢?

?

?

?

?

未完待续

?

转载自:http://chjavach.iteye.com/blog/780979

热点排行