MyReader //專門用於讀取數據的類
|----MyTextReader
|----MyMediaReader
|----MyDataReader
|____MyBufferReader
class MyBufferReader{
MyBufferReader(MyTextReader text){}
MyBufferReader(MyMediaReader media){}
MyBufferReader(MyDataReader data){}
...
}
上面的模式類擴展性很差,可以通過找到其參數的共同類型,通過多態的形式,可以提高擴展性
class MyBufferReader extends MyReader{
private MyReader r;
MyBufferReader(MyReader r){}
...
}
裝飾模式比繼承要靈活,避免了繼承體系的臃腫,而且降低了類與類的關系(繼承結構 --> 組合結構).
裝飾類因為增強已有對象,具備的功能和已有的類是相同的,只是提供了更強的功能,所以裝飾類和被裝飾類通常都屬於同一個體系中的.
import java.io.FileReader; import java.io.IOException; import java.io.Reader; class MyBufferedReader extends Reader { private Reader r; MyBufferedReader(Reader r) { this.r = r; } //可以一次讀一行數據的方法。 public String myReadLine() throws IOException { //定義一個臨時容器。原BufferReader封裝的是字符數組。為了演示方便。定義一個StringBuilder容器。因為最終還是要將數據變成字符串。 StringBuilder sb = new StringBuilder(); int ch; while ((ch = r.read()) != -1) { if (ch == '\r') continue; if (ch == '\n') { return sb.toString(); } else { sb.append((char) ch); } } if (sb.length() != 0) return sb.toString(); return null; } /* 覆蓋Reader類中的抽象方法。read(char[] cbuf, int off, int len)和close()是Reader的抽象方法,必須實現。 */ public int read(char[] cbuf, int off, int len) throws IOException { return r.read(cbuf, off, len); } public void close() throws IOException { r.close(); } public void myClose() throws IOException { r.close(); } } class MyBufferedReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("buf.txt"); MyBufferedReader myBuf = new MyBufferedReader(fr); String line; while ((line = myBuf.myReadLine()) != null) { System.out.println(line); } myBuf.myClose(); } }
import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; public class LineNumberReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("buf.txt"); LineNumberReader lnr = new LineNumberReader(fr); String line; lnr.setLineNumber(2); //設置當前行號。參數:lineNumber - 指定行號的 int 值 while ((line = lnr.readLine()) != null) { System.out.println(lnr.getLineNumber() + ":" + line); } lnr.close(); } }
3:abcde1 #行號從setLineNumber的下一位3開始標記
4:abcde2
5:abcde3
6:abcde4
import java.io.FileReader; import java.io.IOException; import java.io.Reader; public 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 lineNumber; } public String myReadLine() throws IOException { lineNumber++; return super.myReadLine(); } } class MyLineNumberReaderDemo { public static void main(String[] args) throws IOException { FileReader fr = new FileReader("buf.txt"); MyLineNumberReader mylnr = new MyLineNumberReader(fr); mylnr.setLineNumber(200); String line; while ((line = mylnr.myReadLine()) != null) { System.out.println(mylnr.getLineNumber() + "::" + line); } mylnr.myClose(); } }