Z

装饰模式(Decorator Pattern)

Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.

装饰模式用来给子类动态的添加功能,它是继承的补充。还是以代码来举例:

 1abstract class JobCls {
 2    abstract execute(): void;
 3}
 4
 5class Job extends JobCls {
 6    execute() {
 7        console.log("execute job");
 8    }
 9}
10
11class SendBeforeLog extends JobCls {
12    constructor(public job: Job) {
13        super();
14    }
15
16    execute() {
17        this.executeBafore();
18        this.job.execute();
19    }
20
21    executeBafore() {
22        console.log('job will execute');
23    }
24}
25
26class SendAfterLog extends JobCls {
27    constructor(public job: Job) {
28        super();
29    }
30
31    execute() {
32        this.job.execute();
33        this.executeAfter();
34    }
35
36    executeAfter() {
37        console.log('job executed');
38    }
39}
40
41let job = new Job();
42job = new SendBeforeLog(job);
43job = new SendAfterLog(job);
44
45job.execute();

在最基础的Job类中,execute方法已经是原子的了,无法再继续拆分。那么使用装饰模式对其进行功能的添加是一个非常好的方法。上面的代码中有两个装饰类:SendBeforeLog与SendAfterLog,分别对Job运行前后增加功能。在最后的execute执行时,会依次显示出所有console。

也许你会问,我直接Job类的源代码不就好了,那么在有大量同类的情况下,难道还要一个个修改代码么?此时使用装饰模式就是最好的方法。当大量逻辑需要添加同一个功能时,装饰模式是一个不错的选择。

装饰模式最为继承的补充,装饰方法和被装饰方法相互独立,装饰方法无论套用了多少次装饰类,最终仍会执行原本的逻辑。

但装饰模式也有个很大的缺点,就是比较复杂,而且装饰的顺序是固定的,那么在有多层装饰类嵌套时,可能需要阅读源代码才能确定执行顺序,除非所有装饰类执行的顺序是相同的。