一、什么是装饰设计模式?
装饰模式是在不必改变原类文件和使用继续的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是通过装饰来包裹真实的对象。
二、装饰模式的特点:
(1) 装饰对象和真实对象有相同的接口。这样客户端对象就可以以和真实对象相同的方式和装饰对象交互。
(2) 装饰对象包含一个真实对象的索引(reference)
(3) 装饰对象接受所有的来自客户端的请求。它把这些请求转发给真实的对象。
(4) 装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继续来实现对给定类的功能扩展。
自定义代码示例:
/*需求:通过自定义的缓冲流,读取一个文本文件的数据。自定义类要求实现对BufferedReader类的装饰。
即在自定义类中定义一个一次读取一行文本内容的方法 myReadLine();
把读取到的数据显示到控制台上。
注意:在windows系统下的换行符是/r/n。
*/
import java.io.*;
public class MyBufferedReader extends Reader{
/**
* @param args
*/
Reader rf;
public MyBufferedReader(Reader rf) {
this.rf =rf;
}
/*此方法抛出IOException异常*/
public String myReadLine()throws IOException{
int ch;
StringBuilder sb = new StringBuilder();
while((ch=rf.read())!=-1) {
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
sb.append((char)ch);
}
return null;
}
/*覆写 Reader类的close方法*/
public void close() throws IOException {
rf.close();
}
/*覆写 Reader类中抽象方法read(char[] cbuf, int off, int len)*/
public int read(char[] cbuf, int off, int len) throws IOException {
return rf.read(cbuf, off,len);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyBufferedReader mbf =null;
String line = null;
try{
mbf = new MyBufferedReader(new FileReader("MyBufferedReader.java"));
line = mbf.myReadLine();
while(line != null) {
System.out.println(line);
line = mbf.myReadLine();
}
}catch(IOException e) {
e.toString();
}finally{
try{
mbf.close();
}catch(IOException e1) {
e1.toString();
}
}
}
三、装饰模式与继承的比较:
装饰模式: 用来扩展一类对象的功能,不需要子类,动态地 ,运行时分配职责,防止由于子类而导致的复杂和混乱,更多的灵活性
继承:用来扩展特定对象的功能,需要子类,静态地,编译时分派职责, 导致很多子类产生,在一些场合,报漏类的层次,缺乏灵活性
相比而言,在写继承时,要多考虑是否能够用装饰模式让代码更简洁、优化。