装饰模式(Decorator Pattern)
Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.
装饰模式用来给子类动态的添加功能,它是继承的补充。还是以代码来举例:
abstract class JobCls {
abstract execute(): void;
}
class Job extends JobCls {
execute() {
console.log("execute job");
}
}
class SendBeforeLog extends JobCls {
constructor(public job: Job) {
super();
}
execute() {
this.executeBafore();
this.job.execute();
}
executeBafore() {
console.log('job will execute');
}
}
class SendAfterLog extends JobCls {
constructor(public job: Job) {
super();
}
execute() {
this.job.execute();
this.executeAfter();
}
executeAfter() {
console.log('job executed');
}
}
let job = new Job();
job = new SendBeforeLog(job);
job = new SendAfterLog(job);
job.execute();
在最基础的Job类中,execute方法已经是原子的了,无法再继续拆分。那么使用装饰模式对其进行功能的添加是一个非常好的方法。上面的代码中有两个装饰类:SendBeforeLog与SendAfterLog,分别对Job运行前后增加功能。在最后的execute执行时,会依次显示出所有console。
也许你会问,我直接Job类的源代码不就好了,那么在有大量同类的情况下,难道还要一个个修改代码么?此时使用装饰模式就是最好的方法。当大量逻辑需要添加同一个功能时,装饰模式是一个不错的选择。
装饰模式最为继承的补充,装饰方法和被装饰方法相互独立,装饰方法无论套用了多少次装饰类,最终仍会执行原本的逻辑。
但装饰模式也有个很大的缺点,就是比较复杂,而且装饰的顺序是固定的,那么在有多层装饰类嵌套时,可能需要阅读源代码才能确定执行顺序,除非所有装饰类执行的顺序是相同的。