持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天
介绍
- 装饰器模式(Decorator Pattern) 也称为包装模式(Wrapper Pattern) 是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。装饰器模式的核心是功能扩展,使用装饰器模式可以透明且动态地扩展类的功能。
- 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
使用场景
-
扩展一个类的功能。为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
-
动态增加功能,动态撤销。装饰器模式就是使用在对已有的目标功能存在不足,需要增强时,前提是目标存在抽象接口。
应用实践
职责明确
-
抽象组件(Component): 可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象的行为;
-
具体组件(
ConcreteComponent
): 实现/继承Component的一个具体对象,也即被装饰对象; -
抽象装饰器(Decorator): 通用的装饰
ConcreteComponent
的装饰器,其内部必然有一个属性指向Component抽象组件;其实现一般是一个抽象类,主要是为了让其子类按照其构造形式传入一个Component抽象组件; -
具体装饰器(
ConcreteDecorator
): Decorator的具体实现类,理论上,每个ConcreteDecorator
都扩展了Component对象的一种功能;
实现
//抽象组件
abstract class Component {
public abstract void execute();
}
//实体组件继承抽象组件(需要被装饰的组件)
class ConcreteComponent extends Component {
constructor(name) {
this.name = name;
}
execute() {
console.log('我是一个纯纯的组件', this.name)
}
}
//抽象装饰器
abstract class Decorator {
private componentInstance
constructor(component) {
this.componentInstance = component;
}
execute() {
this.componentInstance.execute()
}
}
// 创建装饰器
class ConcreteDecorator extends Decorator {
constructor(component) {
super()
this.componentInstance = component;
}
beforeMount() {
console.log('组件执行前操作')
}
mount(
console.log('组件执行完成')
)
execute() {
beforeMount()
this.componentInstance.execute()
mount()
}
}
//使用
const component = new ConcreteComponent()
const decoratorInstance = new ConcreteDecorator(component)
//执行调用
decoratorInstance.execute()
汇总
装饰器(修饰)模式,是面向对象程式领域中,一种动态地往一个类别中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类别更为灵活,这样可以给某个对象而不是整个类别添加一些功能。
优点特性
-
装饰器模式与继承关系的目的都是要扩展对象的功能,但是装饰器模式可以提供比继承更多的灵活性。当需要扩展多个功能时,装饰器模式只需要增加新的具体装饰类即可,而继承关系则需要继承原有类,再进行扩展,如果需要在不改变原有类的基础上继续扩展,则需要再次继承,这样代码耦合性比较高。
-
可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
-
通过使用不同的具体装饰器类以及这些装饰器类的排列组合,可以创建出很多不同的组合。可以使用多个具体装饰类来装饰同一个对象。
-
具体构建类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰器类,在使用时再对其进行组合额,原有代码无线改变,符合“开闭原则”。
缺点弊端
- 装饰器模式会增加许多子类,过度使用会增加程序得复杂性。装饰方式可能比较复杂,如果嵌套太多,容易造成代码可读性变差和出错。