装饰者设计模式
2009-02-21 17:39
423 查看
定义:动态将扩展功能附加到对象上,替代继承的另一种选择。类图如下:
(图片引自http://www.cnblogs.com/NeeoMeng/articles/1127974.html)
定义看起来不是很好理解,其实只要用过Java IO,我们已经在用装饰者这种设计模式了 -, -
先看看java io package里对于有关InputStream类的分布情况
上图中,FilterInputStream即可被看作Decorator Class。
照猫画虎,我们也可以编写自己的Java I/O装饰着对象了。
如实现将输入流内所有字符变为大写或者小写。我们需要做的仅仅是继承FilterInput类,覆写两个方法即可。
问题来了,为什么不直接同StreamBufferInputStream类一样继承InputStream实现转换大小写的功能呢?
其实,如果只是单纯的继承关系,那么我们想实现既用Buffer,又要让它大小写转换将怎么办呢~建个UpperCaseStringBufferInputStream同样继承InputStream? 此方法肯定不是王道,逐渐的,类会多的让人想死,Java的设计者自然也想到了这样的问题。
用装饰者模式可以轻松解决爆炸式类继承的问题,如果还有点晕,看了下面代码估计就懂了。
UpperCaseInputStream类,继承FilterInputStream
覆写InputStream里的两个主要read()方法
同理,Java I/O中的Reader类也是采用了装饰者的设计模式
Reader比InputStream相对复杂点,如果某些方法或者构造函数不知如何覆写,可参照JDK源码中同样继承Reader的相关类,如BufferedReader.
两个重要的方法,依旧是read()
LowerCaseReader类继承自FilterReader
编写个简单的测试类:
ReaderTest
(图片引自http://www.cnblogs.com/NeeoMeng/articles/1127974.html)
定义看起来不是很好理解,其实只要用过Java IO,我们已经在用装饰者这种设计模式了 -, -
先看看java io package里对于有关InputStream类的分布情况
上图中,FilterInputStream即可被看作Decorator Class。
照猫画虎,我们也可以编写自己的Java I/O装饰着对象了。
如实现将输入流内所有字符变为大写或者小写。我们需要做的仅仅是继承FilterInput类,覆写两个方法即可。
问题来了,为什么不直接同StreamBufferInputStream类一样继承InputStream实现转换大小写的功能呢?
其实,如果只是单纯的继承关系,那么我们想实现既用Buffer,又要让它大小写转换将怎么办呢~建个UpperCaseStringBufferInputStream同样继承InputStream? 此方法肯定不是王道,逐渐的,类会多的让人想死,Java的设计者自然也想到了这样的问题。
用装饰者模式可以轻松解决爆炸式类继承的问题,如果还有点晕,看了下面代码估计就懂了。
UpperCaseInputStream类,继承FilterInputStream
覆写InputStream里的两个主要read()方法
import java.io.*; public class UpperCaseInputStream extends FilterInputStream{ public UpperCaseInputStream(InputStream in) { super(in); } public int read() throws IOException{ int c = super.read(); return c == -1 ? c : Character.toUpperCase(c); } public int read(byte[] b, int offset, int length) throws IOException { int c = super.read(b, offset, length); for(int i = offset; i < offset+length; i++){ b[i] = (byte)Character.toUpperCase((char)b[i]); } return c; } }
同理,Java I/O中的Reader类也是采用了装饰者的设计模式
Reader比InputStream相对复杂点,如果某些方法或者构造函数不知如何覆写,可参照JDK源码中同样继承Reader的相关类,如BufferedReader.
两个重要的方法,依旧是read()
LowerCaseReader类继承自FilterReader
public class LowerCaseReader extends FilterReader{ private Reader r; public LowerCaseReader(Reader r){ super(r); this.r = r; } public void close() throws IOException { // TODO Auto-generated method stub synchronized (lock) { if (r == null) return; r.close(); r = null; } if (r == null) return; else r.close(); } public int read() throws IOException{ int c = super.read(); return c == -1 ? c : Character.toLowerCase((char)c); } public int read(char[] ch, int offset, int length) throws IOException { int c = super.read(ch, offset, length); for(int i = offset; i < offset+length; i++){ ch[i] = (char)Character.toLowerCase((char)ch[i]); } return c; } }
编写个简单的测试类:
ReaderTest
public class ReaderTest { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { int c; String line = null; // UpperCaseInputStream // 装饰类如何用 InputStream in = new UpperCaseInputStream(new FileInputStream("test.txt")); while((c = in.read()) > 0){ System.out.print((char)c); } in.close(); in = null; // LowerCaseReader // 喜欢ReadLine的朋友可以做Reader的装饰类 // BufferedReader被LowerCaseReader所修饰 // 多写几个修饰类,由于构造函数接的都是Reader,当然可以叠加 // Java的向下转型在修饰者的应用中起了相当关键的作用 BufferedReader br = new BufferedReader(new LowerCaseReader(new FileReader("test2.txt"))); // BufferedReader的readLine方法调用fill调用Reader的read方法 // 由于构造时是以LowerCaseReader构造,所以实际上调用了其read方法,讲小写显示 while((line = br.readLine()) != null){ System.out.println(line); } br.close(); br = null; } }
相关文章推荐
- 设计模式之装饰者模式
- 设计模式(8)—— 装饰者模式(Decorator Pattern)
- 装饰者设计模式
- 23种设计模式(11):装饰者模式
- JAVA设计模式初探之装饰者模式
- 设计模式之装饰者模式
- 设计模式:装饰者模式
- 设计模式 装饰者模式 带你重回传奇世界
- 装饰者设计模式的使用
- 设计模式之装饰者模式
- Java设计模式之装饰者模式
- 设计模式之装饰者模式
- C#设计模式--装饰者模式
- 设计模式——装饰者模式
- 结合项目实例 回顾传统设计模式(三)装饰者模式
- 设计模式总结2--装饰者模式
- 设计模式之间区别 (2) 装饰者模式和继承
- 设计模式之装饰者模式
- 设计模式——装饰者模式
- 23种设计模式之装饰者模式