1.前言
装饰模式:动态的给一个类添加一些额外职责,就增加功能来说,装饰模式比生成子类更加灵活。
装饰模式属于结构型模式,它是作为现有的 类的⼀个包装,允许向⼀个现有的对象添加新的功能, 同时⼜不改变其结构。
什么情况下我们会使用装饰模式呢?
- 一般来说当我们想要以动态或者透明的方式给一个类增加职责但又不改变其结构的情况下,我们常常会使用到装饰模式。
2.核心组成
- 抽象组件(Component):定义装饰⽅法的规范
- 被装饰者(ConcreteComponent):Component的具体实现,也就是我们要装饰的具体对象
- 装饰者组件(Decorator):定义具体装饰者的⾏为规范, 和Component⻆⾊有相同的接⼝,持有组件(Component)对象的实例引⽤
- 具体装饰物(ConcreteDecorator):负责给构件对象装饰附加的功能
3.代码实现
在这里我们使用一个简单的例子来实现装饰模式:
比如很多饮品都是水加调料调制而成,这里水就是被装饰者,而具体的装饰物就是调料。
Component
/**
* @Author: 少不入川
* @Date: 2023/1/9 19:32
*/
public interface DrinkComponent {
void operation();
}
ConcreteComponent
public class WaterComponent implements DrinkComponent{
@Override
public void operation() {
System.out.print("水...");
}
}
Decorator
public class DrinkDecorator implements DrinkComponent{
protected DrinkComponent component;
public void setComponent(DrinkComponent component) {
this.component = component;
}
@Override
public void operation() {
if(component != null){
component.operation();
}
}
}
ConcreteDecorator
public class SugarDecorator extends DrinkDecorator{
public void operation() {
component.operation();
System.out.print("加冰糖...");
}
}
/*----------------------------------------------------*/
public class TeaDecorator extends DrinkDecorator{
public void operation() {
this.component.operation();
System.out.print("加茶叶...");
}
}
Test
public class DecoratorTest {
public static void main(String[] args) {
WaterComponent water = new WaterComponent();
SugarDecorator sugarDecorator = new SugarDecorator();
sugarDecorator.setComponent(water);
sugarDecorator.operation();
TeaDecorator teaDecorator = new TeaDecorator();
teaDecorator.setComponent(water);
teaDecorator.operation();
}
}
4.UML类图
5.优点与缺点
- 优点
- 装饰模式与继承关系的⽬的都是要扩展对象的功能,但 装饰模式可以提供⽐继承更多的灵活性。
- 装饰模式可以将类中的“装饰”功能从类中搬移去除,从而可以简化原有的类。
- 使⽤不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同⾏为的组合,原有代码⽆须改变,符合“开闭原则”
- 缺点
- 装饰模式增加了许多⼦类,如果过度使⽤会使程序变得 很复杂 (多层包装)
简化原有的类**。 - 使⽤不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同⾏为的组合,原有代码⽆须改变,符合“开闭原则”
- 装饰模式增加了许多⼦类,如果过度使⽤会使程序变得 很复杂 (多层包装)