------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
概念(纯个人理解):
想创建一个B类,在A类的基础上增强一些功能,但考虑到更改A类的代码时可能会导致一些错误。因此在B类的构造方法中接受A类的引用,在B类中基于A的对象提供更强功能。这种设计模式就叫装饰设计模式。
装饰与继承的区别:
继承的逻辑结构:
Reader
|-- TextReader
|--BufferedTextReader
|-- MediaReader
|--BufferedMediaReader
|-- DataReader
|--BufferedDataReader
说明:通过上面的框架可以看出,如果Reader类下面还有其他子类,并想对此子类进行Buffered功能时,仍需要再继承一个。这就造成了代码臃肿。
装饰的逻辑结构:
Reader
|-- TextReader
|-- MediaReader
|-- DataReader
|--BufferedReader(Reader r)
装饰设计模式,则是将修饰类,与被装饰的类放在同一级别中。找到被装饰类们的共同类型,将其传递到装饰类的构造方中。
package com.lxh.io;
import java.io.*;
// 装饰类与被装饰类是同一级别的,都继承了同一个父类。
public class MyBufferedReader extends Reader {
// 创建构造函数,且该构造函数的参数为抽象出来的同一类型。传入一个FileReader
private Reader r;
// 构造函数没有返回类型,因为类的名称,就是返回类型了。
public MyBufferedReader(Reader r) {
this.r = r;
}
public String myReadLine() throws IOException{
int ch;
StringBuilder sb = new StringBuilder();
// FileReader的返回值是int类型的字符。
while((ch = r.read()) != -1) {
//当判断结尾是\r\n 时,返回字符串。
if(ch == '\r')
continue;
if(ch == '\n')
//将StringBuilder转换成为String类型。
return sb.toString();
// 将int转换成char
sb.append((char)ch);
}
// 当最后一行时,如果结尾处没有回车,在while循环中就不能将这一行字符加到
// StringBuffer中,故此需要再判断一次。
if(sb.length() != 0) {
return sb.toString();
}
//当是流的最后时,返回null。
return null;
}
// close()方法
public void myClose() throws IOException{
r.close();
}
// 实现read方法的抽象方法。
public void close() throws IOException {
r.close();
}
public int read(char[] cbuf, int off, int len) throws IOException {
return r.read(cbuf, off, len);
}
}
package com.lxh.io;
import java.io.*;
import java.io.FileReader;
import java.io.IOException;
public class TestMyBuffer {
public static void main(String[] args) {
MyBufferedReader myBuf = null;
FileReader fr = null;
try {
fr = new FileReader("BufferdWriterDemo.txt");
myBuf = new MyBufferedReader(fr);
String line = null;
while((line = myBuf.myReadLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
myBuf.myClose();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
MyLinebumberReader
添加个功能。
getLineNumber
setLineNumber
readLine
因为很多的方法和MyBufferedReader类中的方法是相同的,所以继承该类。
package com.lxh.io;
import java.io.*;
public class MyLineNumberReader extends MyBufferedReader {
public MyLineNumberReader(Reader r) {
super(r);
// TODO Auto-generated constructor stub
}
private int num ;
// 设置处理num的方法
public void mySetLineNumber(int num) {
this.num = num ;
}
public int myGetLineNumber() {
return this.num ;
}
public String myReadLine() throws IOException{
num++;
return super.myReadLine();
}
}