1、简介
1.1 定义
装饰器模式(Decorator Pattern)增加一个装饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为装饰类的构造函数的参数,可以实现对现有对象功能的拓展,使类功能更加灵活。装饰模式属于结构型模式
1.2 组成结构
- 抽象角色(Component):定义一个可以动态添加任务的抽象接口
- 具体角色(ConcreteComponent):实现 Component 类,定义要被装饰器装饰的对象
- 抽象装饰器(Decorator):维护抽象角色实例,并实现一个与抽象角色接口一致的接口
- 具体装饰器(ConcreteDecorator):给组件增加新的职责、功能
1.3 优缺点
优点:
- 不用改变原来的类
- Decorator 模式与继承的目的都是要扩展对象的功能,但 Decorator 比继承更灵活,耦合度低
- 使用不同的具体装饰类和这些装饰类的组合,可以很方便的进行动态扩展
缺点:
- 装饰模式会增加很多子类,多层装饰会提高系统的复杂度
1.4 适用场景
- 需要扩展一个类的功能,或者给一个类增加附加职责,而又不能用生成子类的方式(类为 final 或者继承会产生大量子类,类爆炸)进行扩充时
- 需要动态的给一个对象增加功能、而且可以再动态撤销
- 需要增加一些基本功能的排列组合产生的大量功能
1.5 与适配器模式的区别:
- 适配器也可以在转换的时候增加新的职责,但它的主要目的不是这个,装饰器模式才是主要给被装饰者增加职责的
- 适配器模式用新街口调用原接口,原接口对于系统来说是不可见的。装饰器模式原封不动的使用原接口,系统对装饰的对象也通过原接口来完成使用
- 适配器知道被适配者的详细信息,装饰者只知道接口,具体细节运行的时候才知道
2、代码示例
/**
* 抽象角色
*/
public interface Component {
void operation();
}
/**
* 具体角色,实现抽象角色,定义要被装饰器装饰的对象
*/
public class ConcreteComponent implements Component{
public ConcreteComponent(){
System.out.println("创建具体角色");
}
@Override
public void operation() {
System.out.println("调用具体角色的方法 operation()");
}
}
/**
* 抽象装饰角色,实现与抽象角色一致的接口
*/
public abstract class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
public void operation(){
component.operation();
}
}
/**
* 具体装饰器,给
*/
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addFunction();
}
public void addFunction() {
System.out.println("为具体角色增加的额外功能 addFunction() ~~~");
}
}
public class DecoratorTest {
public static void main(String[] args) {
// 调用具体的角色的方法
ConcreteComponent concreteComponent = new ConcreteComponent();
concreteComponent.operation();
// 通过装饰器调用具体的角色,并增加额外的功能
ConcreteDecorator concreteDecorator = new ConcreteDecorator(concreteComponent);
concreteDecorator.operation();
}
}