|--什麼是裝飾模式。
裝飾模式:是你還是你,一切拜託你(借用老崔經典詞)。
它是由繼承出現的。先有繼承,再有裝飾。
回顧繼承
優點:提高複用性,讓能夠反覆使用。通過方法重寫利用後期擴充套件。
壞處:因為類與類之間的繼承關係。但他們關係增強。耦性也就高了。不符合java宗旨:低耦合。高內聚。
對照方下:
a: 有一個Witer體系
|--TxtWrite
|--Mp3Write
|--DIDWrite
上面是一個普通子類實現。呼叫者認為執行太慢,要求對三者進行增強(高效|緩衝)。改動例如以下
class myBuffereWrite exetends Write{
//接收子類:Fu f = new Zi();
private Write ziWrite;
public BuffereWrite(Write ziWrite)
{
this.ziWrite = ziWrite;
}
public void writeLine(String line)
{
//使用ziWrite進行整容處理。然後一行資料儲存到write中。
}
public void close()
{
ziWrite.clese();//多型(呼叫的還是子類)!
}
public void flash(){
ziWrite.flash();//多型(呼叫的還是子類)。
}
....//重寫Write的抽象方法。呼叫的myBuffereWrite中的,再方法裡邊呼叫是傳送ziWrite。
僅僅只是在呼叫它之前給它做了一些手術。
}
|--總結
1:比方你使用Write的高效功能,那你就建立myBuffereWrite,傳遞你的對其高效的物件,比方FileWrite();
2:裝飾模式體現了對一個物件(功能)的增強(高內聚),然後緊密性比較弱(低耦合)。
3:JDK中用的裝飾就挺多的,比方BufferedWriter(Writer out);PrintStream(OutputStream out);ObjectInputStream(InputStream in)等。
|--程式碼演示樣例
模擬BuffereReader裝飾類
package com.Decoration;
import java.io.IOException;
import java.io.Reader;
/**
* @author hubiao
* 模擬BuffereReader裝飾類
*
* 分析:模擬一個類,就是自定一個類。實現它的特有方法:ReadLine();
* 1:模擬什麼:特有方法
* 2:你有什麼:依據裝飾特點。自定的類繼承一個抽象類,由於BuffereReader的readLine底層也是繼承Reader中的。
* 我們要做的。也是繼承Reader,寫一個與BuffereReader一樣的ReadLine方法來。 */ public class MyBuffere extends Reader { /*Reader是一個抽象類的父類。將須要高效的類都實現了它。
都是它的子類。
*/ private Reader reader = null; public MyBuffere(Reader reader){ this.reader = reader; } public int read(char[] cbuf, int off, int len) throws IOException { return reader.read(cbuf, off, len); } public String readLine() throws IOException { /** * 1:這裡要思考,使用 * A:read(char[] cbuf, int off, int len);一次讀取一緩衝區 * B:read();//一次讀取一個字串 * 2:分析 * 我們模擬readLine目的是為了模擬什麼?還不是為了實現BufferedReader中的readerLine一次讀取一行的高效方法。 * 然後使用A方法不合適,由於它一次讀取一個char容量定義的長度,我們封裝好的程式碼非常難獲知呼叫者要讀取的資料文字的每行資料有多長。
* 使用B方法的優點,是一次讀取一個字元,當遇到\r\n就說明是一行的結束。則說一行讀取完成,那怎麼一行的資料每一個字元用什麼儲存呢? * 使用String, 這...太可怕了吧。由於我們知道String在java中是一個常量池。
一但賦值,將不可變。
所以選擇效率高的StringBuilder * 把每一個字元拼接到StringBuffer中。再返回給呼叫者。 */ //單字元容器 StringBuffer buffer = new StringBuffer(); //每一個字元 int read = 0; while((read = reader.read())!=-1) { char chr = (char) read; if(chr=='\r') continue; if(chr=='\n') return buffer.toString(); else buffer.append(chr); } //防止讀取的是最後一行。則沒有\r\n。那麼再推斷緩衝區中是否有值?假設有,則再返回。 if(buffer.length() > 0 ) return buffer.toString(); else return null; } public void close() throws IOException { reader.close(); } }
模擬LineNumberReader
/**
* @author hubiao
* 模擬LineNumberReader
* 也是相同,模擬,就是自定一個類,模擬需求給出的特殊方法:獲取每一個行號,然後讀取每一行。
*/
public class MyLineNumberReader extends Reader{
/*接收傳遞子類物件,Fu f = new Zi();//多型*/
private Reader reader;
private int lineNumber;//行號
public MyLineNumberReader(Reader reader) {
this.reader = reader;
}
public int read(char[] cbuf, int off, int len) throws IOException {
return reader.read(cbuf, off, len);
}
public String readLine() throws IOException
{
//單字元容器
StringBuffer buffer = new StringBuffer();
//每一個字元
int read = 0;
while((read = reader.read())!=-1)//-1表示讀取到流的結尾!
{
char chr = (char) read;
if(chr=='\r')
continue;
if(chr=='\n'){
lineNumber++;
return buffer.toString();
}
else
buffer.append(chr);
}
//防止讀取的是最後一行,則沒有\r\n。那麼再推斷緩衝區中是否有值?假設有,則再返回。
if(buffer.length() > 0 ){ lineNumber++; return buffer.toString(); }else return null; } public void close() throws IOException { reader.close(); } public int getLineNumber() { return lineNumber; } public void setLineNumber(int lineNumber) { this.lineNumber = lineNumber; } }