# 十三.策略模式
- 将定义的一组算法封装起来,使其相互之间可以替换。封装的算法具有一定的独立性,不会随客户端变化而变化。
- 避免大量的 if/else 或 switch/case
# 1.类图
# 2.代码
/* 如果不用策略模式代码都耦合在一起了 */
class Customer {
public type: string;
constructor(type) {
this.type = type;
}
pay(amount) {
if (this.type == "会员顾客") {
return amount * 0.9;
} else if (this.type == "VIP顾客") {
return amount * 0.8;
}
return amount;
}
}
let c1 = new Customer("普通顾客");
console.log(c1.pay(100));
let c2 = new Customer("会员顾客");
console.log(c2.pay(100));
let c3 = new Customer("VIP顾客");
console.log(c3.pay(100));
/* 1、用策略模式改写:可以解耦合 */
class Customer2 {
public kind: any;
constructor(kind) {
this.kind = kind;
}
cost(amount) {
return this.kind.discount(amount);
}
}
class Kind {}
class Normal extends Kind {
discount(amount) {
return amount;
}
}
class Member extends Kind {
discount(amount) {
return amount * 0.9;
}
}
class VIP extends Kind {
discount(amount) {
return amount * 0.8;
}
}
let d1 = new Customer2(new Normal());
console.log(d1.cost(100));
d1.kind = new Member();
console.log(d1.cost(100));
d1.kind = new VIP();
console.log(d1.cost(100));
/* 2、把算法封装在策略对象中,指定算法调用即可 */
class Customer3 {
kinds: object;
constructor() {
this.kinds = {
normal: function(price) {
return price;
},
member: function(price) {
return price * 0.9;
},
vip: function(price) {
return price * 0.8;
},
};
}
cost(kind, amount) {
return this.kinds[kind](amount);
}
}
let c = new Customer3();
console.log(c.cost("normal", 100));
console.log(c.cost("member", 100));
console.log(c.cost("vip", 100));
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
78
79
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
78
79