0%

设计模式之模板方法和策略模式

设计模式基础(2):模板方法&策略模式

介绍模板方法&策略模式的C++示例代码、面向的问题、核心思想

模板方法(Template Method)

面向的需求

固定的方法流程,但是中间步骤的具体实现可能会有变化。

代码示例

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
class Lib{
Lib(){};

public:
void step1(){
//固定步骤1
}

void step3(){
//固定步骤3
}

void step5(){
//固定步骤5
}

virtual step2()= 0; //可变步骤2
virtual step4()= 0; //可变步骤4

void run()
{
step1();
step2();
step3();
step4();
step5();
}

virtual ~Lib(){};
}
1
2
3
4
5
6
7
8
9
10
11
12

class App :public Lib{

virtual step2(){
//子类具体实现该功能
}

virtual step4(){
//子类具体实现该功能
}

}
1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main(){
Lib* lb= new App();
lb->run(); //动态调用子类中step2,step4方法。
delete lb;
}

而如果采用结构化的编程方式,那么Lib中先实现,1,3,5。之后App中实现2,4,并在主函数中调用1-5方法。当2,4需要改变时,或者说需要更多的App时,变化就会太多。示例中面向对象的编程策略,可以更好的复用,尤其是主函数的维护。

总结Template Method的定义

一个操作中的算法骨架(稳定,如同代码中定义的run方法),而一些步骤延迟(变化)到子类中。Template Method使得子类可以(复用)一个算法的结构。重写该算法的某些特定步骤。

策略模式(Strategy)

面向的需求

某些对象所使用的算法可能多种多样,或者说某一类特定的对象需要使用特定的算法来处理。为了剥离算法和对象,采用策略模式。

示例代码

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
class TaxStrategy{
public:
virtual double Calculate(const Context& context)=0;
virtual ~TaxStrategy(){}
};

class CNTax : public TaxStrategy{
public:
virtual double Calculate(const Context& context){
//***********
}
};

class USTax : public TaxStrategy{
public:
virtual double Calculate(const Context& context){
//***********
}
};

class DETax : public TaxStrategy{
public:
virtual double Calculate(const Context& context){
//***********
}
};

//扩展
//*********************************
class FRTax : public TaxStrategy{
public:
virtual double Calculate(const Context& context){
//.........
}
};

class SalesOrder{
private:
TaxStrategy* strategy;

public:
//这个地方包含工厂模式,暂且不管。只需要明确,此处指向具体的某个子类对象
SalesOrder(StrategyFactory* strategyFactory){
this->strategy = strategyFactory->NewStrategy();
}
~SalesOrder(){
delete this->strategy;
}

public double CalculateTax(){
//...
Context context();

double val =
strategy->Calculate(context); //多态调用
//...
}

};

分析代码及思想

一般情况下会采用if-else判断语句加上相应的算法来实现功能。扩展方式也是增加if-else。但是现在则不然,可以利用不同类重写算法,而且保持SalesOrder的相对稳定。

总结模式的定义及关键点

定义:定义一系列算法,将它们逐个封装起来,并且使他们可互相替换(变化)。这种模式使得算法可独立于使用它的客户端程序(稳定)而变化(进行扩展,更多的子类)。

关键点:

  • 在策略模式下是由基类&一系列派生类为组件提供一系列可重用的算法,从而达到,在运行时确定具体使用某种算法。
  • 含有大量if-else判断,通常可以采用策略模式来优化