定义(百度百科):
装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
UML类图:
具体代码:
public abstract class Component { abstract void operation(); } public class ConcreteComponent extends Component { @Override void operation() { System.out.println("ConcreteComponent"); } } public abstract class Decorator extends Component { private Component component; Decorator(Component c){ component = c; } @Override void operation() { component.operation(); } } public class ComponentDecoratorA extends Decorator { ComponentDecoratorA(Component c) { super(c); } private String addedState; @Override void operation() { super.operation(); } public String getAddedState() { return addedState; } public void setAddedState(String addedState) { this.addedState = addedState; } } public class ComponentDecoratorB extends Decorator { ComponentDecoratorB(Component c) { super(c); } @Override void operation() { super.operation(); addBehavior(); } public void addBehavior() { System.out.println("ComponentDecoratorB"); } }
模块说明:
Component:组件对象接口,可以动态的增加职责。
ConcreteComponent:组件的具体对象,实现组件接口,通常为被装饰的对象。
Decorator:所有装饰器的抽象父类,定义一个与组件一致的接口,并且持有Component对象(被装饰的对象)。
ComponentDecoratorA和ComponentDecoratorB:具体的装饰器,对Component对象的扩展。
相关实例:
java中io包中充满了装饰者模式。
应用场景:
1.在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2.当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。
就是组合大于继承。
优缺点:
优点:
1.比继承更加灵活性
2.更容易复用功能
3.简化更抽象定义,更具体的可以交给装饰器
缺点:
1.会产生更多的小粒度的对象
2.装饰模式提供了一种比继承更加灵活机动的解决方案,但同时也意味着比继承更加易于出错,
排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为繁琐。
总结:
对象的动态组合。