研磨设计模式之装饰模式-3(转)
(1)模式功能
??????? 装饰模式能够实现动态的为对象添加功能,是从一个对象外部来给对象增加功能,相当于是改变了对象的外观。当装饰过后,从外部使用系统的角度看,就不再是使用原始的那个对象了,而是使用被一系列的装饰器装饰过后的对象。
??????? 这样就能够灵活的改变一个对象的功能,只要动态组合的装饰器发生了改变,那么最终所得到的对象的功能也就发生了改变。
??????? 变相的还得到了另外一个好处,那就是装饰器功能的复用,可以给一个对象多次增加同一个装饰器,也可以用同一个装饰器装饰不同的对象。
(2)对象组合
??????? 前面已经讲到了,一个类的功能的扩展方式,可以是继承,也可以是功能更强大、更灵活的对象组合的方式。
??????? 其实,现在在面向对象设计中,有一条很基本的规则就是“尽量使用对象组合,而不是对象继承”来扩展和复用功能。装饰模式的思考起点就是这个规则,可能有些朋友还不太熟悉什么是“对象组合”,下面介绍一下“对象组合”。
什么是对象组合
??????? 直接举例来说吧,假若有一个对象A,实现了一个a1的方法,而C1对象想要来扩展A的功能,给它增加一个c11的方法,那么一个方案是继承,A对象示例代码如下:
?
?查看上图会发现,它的结构和装饰模式的结构几乎是一样的:
?????? ?同样的,输出流部分也类似,就不去赘述了。
?????? ?既然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