引用: http://emavaj.blog.163.com/blog/static/13328055720100292818418/
这个模式非常有用
学这个模式,最好的实例就是JDK的输入输出流
那里就是装饰模式最好的解释
先看个简单的代码:
----------装饰接口
public abstract class IShow {
public abstract void show();
}
-----------核心逻辑
public class Person extends IShow {
private IShow s;
public Person(IShow s){
this.s = s;
}
public void show() {
if(s!=null){
s.show();
}
System.out.println("I'am Person");
}
}
-------装饰
public class Cloth extends IShow {
private IShow s;
public Cloth(IShow s){
this.s = s;
}
public void show() {
if(s!=null){
s.show();
}
System.out.println("I'am Cloth");
}
}
测试:(JUnit4)
public void test4(){
Person p = new Person(null);
Cloth c = new Cloth(p);
c.show();
}
结果:
I'am Person
I'am Cloth
核心逻辑和装饰都集成了抽象类,而且都持有一个抽象类的引用(上面为s)
并重写了抽象方法,重写的时候,都是先调用持有的引用的抽象方法,然后再在这个基础上
添加自己的功能,换句话说就是对原来功能进行“装饰”,进行增强
其实就是一个“链”...
Person的责任是负责显示自身(因为没有引用),Cloth也是负责显示自身,但是它持有了Person的引用
所以要先显示Person,才显示自身,如果再有其它类或者对象,持有Cloth的引用,那么就会先执行Cloth的
但是Cloth又先执行Person的,就好像一条链条一样!
可以回到JDK的流操作上
InputStream is = new FileInputStream("xxxx");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
InputStream执行的是核心,就是读一个流
isr是它的装饰,持有了引用is
br也装饰了isr
所以,功能是,先执行读入一个byte流,然后经过isr装饰,变成了字符流,在经过br装饰,变成了有
缓冲功能的字符流
这就是装饰模式!
它使用的场合如下:
一个核心有多个辅助功能,但是这些辅助功能可以自由组合,个数和顺序都可以不同
比如上面的流操作,就可以有N种组合