模版方法模式

  • 定义:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模版方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤

模版方法模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
abstract class AbstractClass {
/**
* The template method defines the skeleton of an algorithm.
*/
public templateMethod(): void {
this.baseOperation1();
this.requiredOperations1();
this.baseOperation2();
this.hook1();
this.requiredOperation2();
this.baseOperation3();
this.hook2();
}

/**
* These operations already have implementations.
*/
protected baseOperation1(): void {
console.log('AbstractClass says: I am doing the bulk of the work');
}

protected baseOperation2(): void {
console.log('AbstractClass says: But I let subclasses override some operations');
}

protected baseOperation3(): void {
console.log('AbstractClass says: But I am doing the bulk of the work anyway');
}

/**
* These operations have to be implemented in subclasses.
*/
protected abstract requiredOperations1(): void;

protected abstract requiredOperation2(): void;

/**
* These are "hooks." Subclasses may override them, but it's not mandatory
* since the hooks already have default (but empty) implementation. Hooks
* provide additional extension points in some crucial places of the
* algorithm.
*/
protected hook1(): void { }

protected hook2(): void { }
}

class ConcreteClass1 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass1 says: Implemented Operation1');
}

protected requiredOperation2(): void {
console.log('ConcreteClass1 says: Implemented Operation2');
}
}

/**
* Usually, concrete classes override only a fraction of base class' operations.
*/
class ConcreteClass2 extends AbstractClass {
protected requiredOperations1(): void {
console.log('ConcreteClass2 says: Implemented Operation1');
}

protected requiredOperation2(): void {
console.log('ConcreteClass2 says: Implemented Operation2');
}

protected hook1(): void {
console.log('ConcreteClass2 says: Overridden Hook1');
}
}
const c1 = new ConcreteClass1()
c1.templateMethod()
const c2 = new ConcreteClass2()
c2.templateMethod()