一、概念
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类更为灵活。
二、结构图
2.1、Component
定义一个接口,可以给这些对象动态的添加职责。
public interface Component {void operation();}
2.2、ConcreteComponent
定义了一个具体的对象,也可以给这个对象添加一些职责。
public class ConcreteComponent implements Component{@Overridepublic void operation() {System.out.println("具体对象的操作。");}}
2.3、Decorator
装饰抽象类,继承了Component从外部来扩展Component类的功能,但对于Component来说,是无需知道Decorator的存在的。
public class Decorator implements Component{protected Component component;public Decorator() {}public void setComponent(Component component){this.component = component;}@Overridepublic void operation() {if (component != null){component.operation();}}}
2.4、ConcreteDecorator
具体的装饰对象,起到给Component添加职责的功能。
/*** ConcreteDecoratorA**/public class ConcreteDecoratorA extends Decorator {private String addedState;@Overridepublic void operation() {super.operation();addedState = "new state";System.out.println("具体装饰对象A的操作。");}public String getAddedState() {return addedState;}public void setAddedState(String addedState) {this.addedState = addedState;}}/*** ConcreteDecoratorB**/public class ConcreteDecoratorB extends Decorator {@Overridepublic void operation() {super.operation();addedBehavior();System.out.println("具体装饰对象B的操作。");}private void addedBehavior() {System.out.println("addedBehavior");}}
2.5、客户端代码
装饰的方式是:首先用ConcreteComponent实例化对象component,然后用ConcreteDecoratorA的实例化对象decoratorA来包装component,再用ConcreteDecoratorB的对象decoratorB包装decoratorA,最终执行decoratorB的operation方法。
public static void main(String[] args) {ConcreteComponent component = new ConcreteComponent();ConcreteDecoratorA decoratorA = new ConcreteDecoratorA();ConcreteDecoratorB decoratorB = new ConcreteDecoratorB();decoratorA.setComponent(component);decoratorB.setComponent(decoratorA);decoratorB.operation();}
如果只有一个ConcreteComponent类,那么可以考虑去掉抽象的Component类(接口),把Decorator作为一个ConcreteComponent子类。如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类,甚至在只有两个ConcreteDecorator类的情况下,都可以这样做。
三、总结
3.1、优点
1、装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。2、通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
3.2、缺点
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
3.3、适用场景
1、扩展一个类的功能。2、动态增加功能,动态撤销。
