引言
设计模式,即Design Patterns,是指在软件设计中,被反复使用的一种代码设计经验。使用设计模式的目的是为了可重用代码,提高代码的可扩展性和可维护性。
定义
结构型模式
装饰器模式:允许向一个现有的对象添加新的功能,同时又不改变其结构
我们开发业务时,经常会碰见这样的情况。架构组或其他业务线提供的某个基础模块或者基础业务模块刚好满足大部分的业务需求,但是又有少部分需求无法满足。错误的做法是 要求模块的开发者支持此功能,这样会导致模块的臃肿以及业务的耦合。
此时我们就得使用装饰器模式,在不改变原有模块的基础上自行扩展功能。既不影响对方业务,又不耽误自己开发。
特点
对于装饰器模式而言,开发人员是允许访问目标模块,这也是 装饰器模式 和 代理模式 的区别之一。
优点
- 遵守开闭原则
- 装饰器模式可以组合使用,增加不同的功能,并且可以复用
- 装饰器模式比继承灵活,可以动态添加功能
缺点
- 装饰器模式增加类的数量
- 装饰器模式增加系统的复杂程度
如果想添加不同业务或者不同类型的功能时,就会新创建与之对应的装饰器类;最终模块的实现也是同时依赖多个装饰器和目标模块,系统的复杂程度有所增加。
实现
在装饰之前,我们需要清楚 目标模块具有哪些公共属性和方法。
目标模块
class TargetModule {
method1() {
console.log('targetModule 执行 method1');
}
method2() {
console.log('targetModule 执行 method2');
}
}
装饰器1
class Decorator1 {
module;
constructor(targetModule) {
this.module = targetModule
}
method1() {
console.log('Decorator1 增加功能');
this.module.method1();
}
method2() {
console.log('Decorator1 增加功能');
this.module.method2();
}
}
装饰器2
class Decorator2 {
module;
prop1;
prop2;
constructor(targetModule) {
this.module = targetModule
}
method1() {
console.log('Decorator2 增加功能');
this.module.method1();
}
method2() {
console.log('Decorator2 增加功能');
this.module.method2();
}
}
具体使用
const targetModule = new TargetModule();
const decorator1Module = new Decorator1(targetModule); //使用Decorator1动态增加功能
const decorator2Module = new Decorator2(decorator1Module); //使用Decorator2动态增加功能
// 三个实例对象都可以直接使用
targetModule.method1();
// 输出:
// targetModule 执行 method1
decorator1Module.method1();
// 输出:
// Decorator1 增加功能
// targetModule 执行 method1
decorator2Module.method1();
// 输出:
// Decorator2 增加功能
// Decorator1 增加功能
// targetModule 执行 method1
说明:增加功能时,只需要修改适配器。
应用场景
这里只讨论前端的装饰场景。
- 基础组件按照各业务线的具体需求进行装饰