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)裝飾者會導致設計中出現許多小對象,如果過度使用,會讓程序變得很複雜。



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章