特点:
①装饰者和被装饰着具有相同的超类型;所以在任何需要原始对象(被包装)的场合,都可以用装饰过的对象来代替他;
②可以有一个或者多个装饰者包装一个对象;
③装饰者可以在所委托被装饰者的行为之前或者之后加上自己的行为,以达到特定的目的;即对象可以在任何时候被装饰,所以可以在运行时动态地、不限量第用你喜欢的装饰者来装饰对象。
优缺点
优点:1)提供比继承更多的灵活性 2)使用不同的装饰组合可以创造出不同行为的组合 3)需要的类的数目减少
缺点:1)灵活性带来比较大的出错性 2)产生更多的对象,给查错带来困难
下面引用这篇博客http://www.cnblogs.com/justinw/archive/2007/06/11/779356.html的理解。
Component(被装饰对象基类)
定义对象的接口,可以给这些对象动态增加职责;
ConcreteComponent(具体被装饰对象)
定义具体的对象,Decorator可以给它增加额外的职责;
Decorator(装饰者抽象类)
维护一个指向Component实例的引用,并且定义了与Component一致的接口;
ConcreteDecorator(具体装饰者)
具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责;
Decorator是装饰者模式里非常特殊的一个类,它既继承于Component【IS A关系】,又维护一个指向Component实例的引用【HAS A关系】,换个角度来说,Decorator跟Component之间,既有动态组合关系又有静态继承关系, (动态和静态的问题,所谓动态是说可以在系统运行时(RunTime)动态给对象增加其它职责而不需要修改代码或重新编译;所谓静态是说必须通过调整代码(DesignTime)才能给对象增加职责,而且系统还需要重新编译;从具体技术层面来说,对象的组合和继承正好对应于前面的动态和静态,因为通过对象组合建立的交互关系不是在代码中(DesignTime)固定死的,而是在运行时(RunTime)动态组合的;而通过继承建立的关系是僵硬的难以改变的,因为它是在代码中(DesignTime)固定死了的,根本不存在运行时(RunTime)改变的可能。) WHY? 这里为什么要这么来设计?上面我们说过,组合的好处是可以在运行时给对象增加职责,Decorator【HAS A】Component的目的是让ConcreteDecorator可以在运行时动态给ConcreteComponent增加职责,这一点相对来说还比较好理解;那么Decorator继承于Component的目的是什么?在这里,继承的目的只有一个,那就是可以统一装饰者和被装饰者的接口,换个角度来说,不管是ConcretComponent还是ConcreteDecorator,它们都是 Component,用户代码可以把它们统一看作Component来处理,这样带来的更深一层的好处就是,装饰者对象对被装饰者对象的功能职责扩展对用户代码来说是完全透明的,因为用户代码引用的都是Component,所以就不会因为被装饰者对象在被装饰后,引用它的用户代码发生错误,实际上不会有任何影响,因为装饰前后,用户代码引用的都是Component类型的对象,这真是太完美了!装饰者模式通过继承实现统一了装饰者和被装饰者的接口,通过组合获得了在运行时动态扩展被装饰者对象的能力。
抽象构件角色java 代码
package decorator;
/**
* 装饰者和原组建的共同方法接口(抽象构件角色)
* @author mouca.he
*
*/
public interface InterfaceComponent {
/**
* 组件方法 say()
*
*/
public void say();
}
具体构件角色java 代码
package decorator;
/**
* 原组件(具体构件角色)
* @author mouca.he
*
*/
public class Component implements InterfaceComponent{
public void say() {
// TODO 自动生成方法存根
System.out.println("Component.say():原组件的方法!");
}
}
抽象装饰者角色java 代码
package decorator;
/**
* 抽象装饰者
* @author mouca.he
*
*/
public abstract class AbstractDecorator implements InterfaceComponent{
private InterfaceComponent component;
public AbstractDecorator(InterfaceComponent component){
this.component = component;
}
/**
* 组件方法执行前预处理方法
*
*/
protected void preSay(){};
/**
* 组件方法执行后处理方法
*
*/
protected void afterSay(){};
public void say(){
preSay();
component.say();
afterSay();
};
}
具体装饰者二java 代码
package decorator;
/**
* 装饰者二
* @author mouca.he
*
*/
public class DecoratorTwo extends AbstractDecorator{
public DecoratorTwo(InterfaceComponent component) {
super(component);
// TODO 自动生成构造函数存根
}
/**
* 根据需要重载模板类preSay()方法
*/
protected void preSay(){
System.out.println("DecoratorTwo.preSay():装饰者二的preSay()方法!");
}
/**
* 根据需要重载模板类afterSay()方法
*/
protected void afterSay(){
System.out.println("DecoratorTwo.afterSay():装饰者二的afterSay()方法!");
}
}
装饰者一java 代码
package decorator;
/**
* 装饰者一
* @author mouca.he
*
*/
public class DecoratorOne extends AbstractDecorator{
public DecoratorOne(InterfaceComponent component) {
super(component);
// TODO 自动生成构造函数存根
}
/**
* 根据需要重载模板类preSay()方法
*/
protected void preSay(){
System.out.println("DecoratorOne.preSay():装饰者一的preSay()方法!");
}
/**
* 根据需要重载模板类afterSay()方法
*/
protected void afterSay(){
System.out.println("DecoratorOne.afterSay():装饰者一的afterSay()方法!");
}
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
InterfaceComponent interfaceComponent = new DecoratorTwo(new DecoratorOne(new Component()));
interfaceComponent.say();
/*
* 控制台输出:
* DecoratorTwo.preSay():装饰者二的preSay()方法!
* DecoratorOne.preSay():装饰者一的preSay()方法!
* Component.say():原组件的方法!
* DecoratorOne.afterSay():装饰者一的afterSay()方法!
* DecoratorTwo.afterSay():装饰者二的afterSay()方法!
*/
}
}