设计模式之装饰者模式(二)

 装饰者模式在实际中的应用是java输入输出流,java.io中的类很庞大,我们在学习的时候,看到如此众多的类都觉得无从下手,实际上是因为java.io中使用了装饰者模式,大量的类都是装饰者。

 

比如FileInputStream类,FileInputStream用来读取文本文件,是被装饰者,而它的装饰者有BufferedInputStream和LineNumberInputStream,因为有了这两个装饰者,读取文件时使用FileInputStream可以通过缓冲输入,还能计算行数。

 

 所以我们就可以写一个继承自FilterInputStream的类,重写两个read方法来定制自己的装饰者类了。

 例如我写了一个UpperCaseInputStream的类,这个类继承自FilterInputStream,重写了两个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((char)(c)));
	}
	public int read(byte[] b,int offset,int length)throws IOException//覆写针对字节数组的方法
	{
		int result=super.read(b,offset,length);
		for(int i=offset;i<offset+result;i++)
		{
			b[i]=(byte)Character.toUpperCase((char)b[i]);
		}
		return result;
	}
}

 测试类

import java.io.*;
public class  TestUpperCaseInputStream 
{
	public static void main(String[] args) throws Exception
	{
		InputStream in;
		in=new FileInputStream("F:\\my\\java\\设计模式\\装饰模式\\src\\装饰模式的应用\\test.txt");//FileInputStream相当于被装饰者
		in=new BufferedInputStream(in);//用缓冲流来装饰
		in=new UpperCaseInputStream(in);//用自己写的流来装饰
		int c;
		//读取流
		while((c=in.read())>=0)
		{
			System.out.print((char)c+" ");
		}
		in.close();
	}
}

 test.txt中的内容是(随手写了句歌词。。。)

 

输出结果是

 并且我发现了一个小规律,就是一般如果构造方法中包含一个带有输入流参数的引用的一般是装饰者类,如果没有的话一般就是被装饰者类。

 比如:

 FilterInputStream只有一个构造方法public FilterInputStream(InputStream in)
说明它是装饰者

  FileInputStream则没有类似的构造方法,说明它是被装饰者。

可以看出,装饰者设计模式有个缺点就是很难了解它的设计方式,学习者很容易看得一头雾水,但这个并不影响它的使用。

总结:

   学习了这几个设计模式以后,觉得学习设计模式还是很有用的,在学习装饰者设计模式之前,我并不知道原来java.io类里面的构造到底是怎么样的,为什么有时候需要在构造方法中指定引用,但有时候就不需要,学完了以后才恍然大悟,所以说学习设计模式对于理解java基础知识是非常有帮助的。还有就是,学了设计模式以后,也更加理解了面向对象的概念。

 学习设计模式,我觉得要写代码和画类图结合,否则很难了解这个设计模式到底是怎么用的,而且一定要用生活中的例子去理解,去应用,这是我这几天学习的体会。

posted on 2015-01-21 14:14  qingfei  阅读(113)  评论(0编辑  收藏  举报