前言
- 掌握装饰器模式的特征和应用场景
- 了解装饰器模式的优、缺点
一、定义
装饰器模式(Decorator Pattern):指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能)。
二、应用场景
- 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。
- 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承很难实现,而采用装饰器模式却很好实现。
- 当对象的功能要求可以动态的添加,也可以动态的撤销时。
三、基本结构
- 抽象构件角色(Component):定义一个抽象接口以规范准备接收附加责任的对象。
- 具体构件角色(Concrete Component):实现抽象构件,通过装饰角色为其添加一些职责。
- 抽象装饰角色(Decorator):继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
- 具体装饰角色(Concrete Decorator):实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
- 客户端(Client):对具体构件通过具体装饰进行装饰。
四、基本使用
1. 抽象构件角色
public interface Component {
void operate();
}
2. 具体构件角色
public class ConcreteComponent implements Component {
@Override
public void operate() {
System.out.println("原有功能");
}
}
3. 抽象装饰角色
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operate() {
component.operate();
}
}
4. 具体装饰角色
public class ConcreteDecorator1 extends Decorator {
public ConcreteDecorator1(Component component) {
super(component);
}
@Override
public void operate() {
super.operate();
decoratorOperate();
}
private void decoratorOperate() {
System.out.println("新增功能1");
}
}
public class ConcreteDecorator2 extends Decorator {
public ConcreteDecorator2(Component component) {
super(component);
}
@Override
public void operate() {
super.operate();
decoratorOperate();
}
private void decoratorOperate() {
System.out.println("新增功能2");
}
}
5. 客户端
public class Client {
public static void main(String[] args) {
Component component = new ConcreteComponent();
component.operate();
System.out.println("=========装饰1========");
Component decorator1 = new ConcreteDecorator1(component);
decorator1.operate();
System.out.println("=========装饰2========");
Component decorator2 = new ConcreteDecorator2(component);
decorator2.operate();
System.out.println("=========装饰1+2========");
Component decorator3 = new ConcreteDecorator2(decorator1);
decorator3.operate();
System.out.println("=========装饰2+1========");
Component decorator4 = new ConcreteDecorator1(decorator2);
decorator4.operate();
System.out.println("=========装饰1+1========");
Component decorator5 = new ConcreteDecorator1(decorator1);
decorator5.operate();
}
}
总结
1. 优点
- 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
- 通过使用不同装饰类及这些装饰类的排列组合,可以实现不同的效果
- 装饰器模式完全遵守开闭原则
2. 缺点
- 会出现更多的代码,更多的类,增加程序复杂性
- 动态装饰时,多层装饰时会更复杂