装饰模式定义
动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。
装饰模式结构图
装饰模式角色介绍
抽象构件:Component,一个普通业务组件,可以是接口或抽象类,声明业务接口方法。
具体构件,ConcreteComponent,它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法。
抽象装饰类,Decorator,一般是一个抽象类,也是抽象构件的子类;它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
具体装饰类,ConcreteDecorator,它是抽象装饰类的子类,负责扩展构件功能。
装饰模式结构代码
抽象构件:
public interface Component {
void operation();
}
具体构件:
public class ConcreteComponent implements Component {
public void operation() {
System.out.println("我是原始具体构件");
}
}
抽象装饰者:
public abstract class Decoretor implements Component {
protected Component component;
public Decoretor(Component component) {
this.component = component;
}
}
具体装饰者:
public class ConcreteDecorator extends Decoretor {
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
System.out.println("装饰者先进行装饰操作");
component.operation();
}
}
客户端:
public class Client {
public static void main(String[] args) {
//获取原始构件并操作
Component component = new ConcreteComponent();
component.operation();
//对原始构件进行装饰操作
component = new ConcreteDecorator(component);
component.operation();
}
}
装饰模式运行机制
装饰者和具体组件共同实现同一个抽象构件接口;
装饰者持有抽象构件类型的成员变量,该变量代表的是具体构件对象或者上一个装饰者对象;
客户端持有的构件变量开始指向具体构件对象,具体构件对象经过装饰后,客户端持有的构件变量则指向了装饰者对象,该装饰着再次被装饰,构件变量指向再次放生变更,变化如下图:
最终客户端调用最外层装饰者对象,外层装饰者调用内层装饰者,内层装饰者调用具体构件对象,完成装饰操作。
装饰模式解决的核心问题
装饰模式通过组合的方式对普通构件对象进行装饰,以此来达到扩展构件功能的目的。
装饰模式面向对象的设计原则
装饰模式主要强调使用的就是组合复用技术,用组合的方式替换继承的方式,对系统功能进行扩展。