首页 > 代码库 > java装饰设计模式的由来

java装饰设计模式的由来


装饰设计模式:基于已经存在的功能,提供增强的功能

装饰设计模式的由来:

Reader

  ----TextReader

 ----MediaReader

要为子类提供缓冲读的功能

Reader

  ----TextReader

       ----BufferedTextReader

  ----MediaReader

      -----BufferedMediaReader

Reader

  ----TextReader

       ----BufferedTextReader

  ----MediaReader

      -----BufferedMediaReader

  ----OtherReader

      -----BufferedOtherReader

 

既然都是提供缓冲读的功能,那么就可以把这个功能提取出来,单独定义成一个类

谁需要被提高效率,就把谁作为参数传递给这个类的构造方法

class BufferedReader

{

   privateReader r;

 

   publicBufferedReader(Reader r)

   {

         this.r = r;

   }

}

这个体系就成了下边的样子:

Reader

  ----TextReader


  ----MediaReader


  ----OtherReader


  ----BufferedReader

   

 装饰设计模式的特点:

 1:因为是基于已有的功能提供增强的功能,所以还属于原体系

 2:是一个体系简单化了

例子说明:

import java.io.*;
//实现LineNumberReader
class MyBufferedReader //extends Reader
{
	private Reader r;//真正用来读取文件的
	private char[] arr = new char[1024];//相当于缓冲区
	private int index;//数组使用的下标
	private int count;//存储字符个数的变量

	public MyBufferedReader(Reader r)
	{
		this.r = r;
	}

	//实现一次读一个字符的功能
	public int myRead()throws IOException
	{
	   //如果缓冲区中没有数据,从文件中读取数据到缓冲区
	   if(count==0)
		{
	        count = r.read(arr);//从文件中读取数据到缓冲区,返回的是读取的字符的个数
            index = 0;//下标重置为0,从文件中读了一批数据,从下标0开始取
	    }
		if(count<0)
			return -1;
		//从缓冲区中取一个字符
		int num = arr[index];
		//下标加1
		index++;
		//数量减1
		count--;

		return num;
	}
	//实现一次读一行的功能
	//反复调用myRead(),不够一行的时候存储,够一行的时候返回
	public String myReadLine()throws IOException
	{
		  //使用StringBuilder实现存储
		  StringBuilder sb = new StringBuilder();
          int ch;
		  while((ch=myRead())!=-1)
		  {
		      if(ch=='\r')
				  continue;
			  else if(ch=='\n')
				  return sb.toString();
			  else
				  sb.append((char)ch);

		  }
		  return null;
	}

	public void myClose()throws IOException
	{
		r.close();
	}

}
class MyLineNumberReader extends  MyBufferedReader
{
	private int lineNumber;
	public MyLineNumberReader(Reader r)
	{
		super(r);
	}
    public void setLineNumber(int lineNumber)
	{
		this.lineNumber = lineNumber;
	}
	public int getLineNumber()
	{
		return this.lineNumber;
	}
	public String myReadLine()throws IOException
    {
	    ++lineNumber;
		return super.myReadLine();
	}
}
class  Demo7
{
	public static void main(String[] args)throws IOException 
	{
		FileReader fr = new FileReader("Demo5.java");

		//是一个装饰类
		MyLineNumberReader lnr = new MyLineNumberReader(fr);

		String line = null;
		lnr.setLineNumber(99);
		while((line = lnr.myReadLine())!=null)
		{
			System.out.println(lnr.getLineNumber()+":"+line);
		}
		lnr.myClose();
	}
}

1)继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。

2)在设计中,应该允许行为可以被扩展,而无须修改现有的代码。

3)组合和委托可用于在运行时动态地加上新的行为。

4)除了继承,装饰者模式也可以让我们扩展行为。

5)装饰者模式意味着一群装饰者类,这些类用来包装具体组件。

6)装饰者类反映出被装饰的组件类型(事实上,他们具有相同的类型,都经过接口或继承实现)。

7)装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。

8)可以用无数个装饰者包装一个组件。

9)装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。

10)装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。



 

java装饰设计模式的由来