前言
在吐鲁番,有着“早穿棉袄午穿纱,围着火炉吃西瓜”的说法。不管穿什么样的衣服,都没有改变我们人的本质。衣服让我们能满足防寒保暖或是消暑降温的需求。同理,在软件设计开发中,也有类似原理的设计模式,能达到我们拓展功能的目的,也就是我们现在要学习的装饰模式。
是什么
装修模式(Decorator Pattern):一种动态地往一个类中添加新的行为的设计模式。
如上图,在装饰模式中有以下几种角色:
- Component(抽象组件类):是具体组件类和装饰类的父类。其中声明了具体组件类中的业务方法operation。
- ConcreteComponent(具体组件类):抽象组件类的子类,其中实现了抽象组件类中的方法operation。装饰器可以给它增加新的行为。
- Decorator(抽象装饰类):抽象组件类的子类。用于给具体组件类增加职责。其中维护了一个抽象组件类的引用,用于调用装饰之前组件对象中的方法,并通过具体装饰类拓展方法。
- ConcreteDecorator(具体装饰类):抽象装饰类的子类,用于给具体组件类增加职责。
为什么
还是以我们现实生活为例,我们人类能够在不同季节穿不同衣服以应对不同的气温。而不是直接生长着厚厚的皮毛。这让我们能够随时增减衣物。程序设计中也是一样的,灵活的装饰类能帮我们增加一些额外的职责,而不是通过简单的继承来实现。
怎么做
首先我们需要定义一个抽象组件类,它是具体组件类和装饰类共同的父类,其中定义了抽象的业务操作方法供子类去实现。
/**
* 抽象组件类,是具体组件类和装饰类的父类
*/
public interface Component {
/**
* 抽象的业务操作方法
*/
void operation();
}
然后需要定义一个抽象装饰类,其中持有一个抽象组件类的引用。
/**
* 抽象的装饰类,是抽象组件类的子类
*/
public class Decorate implements Component {
/**
* 持有的抽象组件类的引用
*/
private Component component;
public Decorate(Component component){
this.component = component;
}
@Override
public void operation() {
this.component.operation();
}
}
现在就是具体的组件类和装饰类的实现了。在具体装饰类中,我们通过实现父类的业务操作方法,可以增加其他的行为方法。
/**
* 具体的组件类
*/
public class ConcreteComponent implements Component {
/**
* 实现了父类的操作方法,其中实现了具体的业务逻辑
*/
@Override
public void operation() {
System.out.println("ConcreteComponent's operation!");
}
}
/**
* 具体装饰类,是装饰类的子类
*/
public class ConcreteDecorate extends Decorate {
public ConcreteDecorate(Component component) {
super(component);
}
@Override
public void operation() {
super.operation();
addBehavior();
}
/**
* 装饰类为组件类增加的行为方法
*/
private void addBehavior() {
System.out.println("ConcreteDecorate's added behavior");
}
}
最后来测试一下具体的客户端使用:
public class Main {
public static void main(String[] args) {
Component component = new ConcreteComponent();
ConcreteDecorate concreteDecorate = new ConcreteDecorate(component);
concreteDecorate.operation();
}
}