首页 > 代码库 > (三)策略模式-C++实现

(三)策略模式-C++实现

策略模式:定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换,本模式使得算法可独立于使用它的客户而变化。

三种角色:

1、策略:一个抽象类,这个接口定义了若干个算法标识,即多个虚函数,这些个算法的实现在不同场景可能会不一样。

2、具体策略:它实现了策略,实现抽象类中定义个算法标识,即给出具体算法实现。

3、上下文:它依赖于策略抽象类,即上下文 包含 策略声明的指针,上下文中提供一个方法,该方法委托策略调用具体策略所实现的算法。

    C++实现包含三个文件,一个头文件策略类的声明strategy.h,两个源文件strategy.cpp 和context.cpp,一个是具体策略中方法的实现,另一个是上下文的源文件,将测试用的主函数也放在这个文件中。

1、strategy.h

技术分享
 1 #ifndef _STRATEGY_H_
 2 #define _STRATEGY_H_
 3 
 4 //抽象策略类
 5 class ComputeStrategy{
 6 public:
 7     //这里参数是a[] 实际上相当于指针 所以想获取其长度 非常困难(应该获取不了) 所以传入一个个数
 8     virtual double computeScore(double a[], int len) = 0;
 9 };
10 
11 //具体策略类
12 class StrategyOne : public ComputeStrategy
13 {
14 public:
15     double computeScore(double a[], int len);
16 };
17 
18 class StrategyTwo : public ComputeStrategy
19 {
20 public:
21     double computeScore(double a[], int len);
22 };
23 
24 class StrategyThree : public ComputeStrategy
25 {
26 public:
27     double computeScore(double a[], int len);
28 };
29 
30 
31 
32 #endif
View Code

2、strategy.cpp

技术分享
 1 #include "strategy.h"
 2 #include <iostream>
 3 #include <cmath>
 4 #include <algorithm>
 5 
 6 double StrategyOne::computeScore(double a[], int len)
 7 {
 8     double score = 0, sum = 0;
 9     for (int i = 0; i < len; i++)
10     {
11         sum += a[i];
12     }
13     score = sum / len;
14     return score;
15 }
16 
17 double StrategyTwo::computeScore(double a[], int len)
18 {
19     double score = 0, multi = 1;
20     for (int i = 0; i < len; i++)
21     {
22         multi *= a[i];
23     }
24     score = std::pow(multi, 1.0 / len);
25     return score;
26 }
27 
28 double StrategyThree::computeScore(double a[], int len)
29 {
30     double score = 0, sum = 0;
31     if (2 >= len)
32     {
33         return 0.0;
34     }
35 
36     std::sort(a, a + len);
37     for (int i = 1; i < len - 1; i++)
38     {
39         sum += a[i];
40     }
41     score = sum / (len - 2);
42     return score;
43 
44 }
View Code

3、context.cpp

技术分享
 1 #include <iostream>
 2 #include "strategy.h"
 3 
 4 //上下文类 依赖策略类
 5 class Context
 6 {
 7 public:
 8     ComputeStrategy* myStrategy;
 9 public:
10     void setStrategy(ComputeStrategy* strategy)
11     {
12         myStrategy = strategy;
13     }
14     double getPersonScore(double a[], int len)
15     {
16         if (NULL != myStrategy)
17         {
18             std::cout << "myStrategy not null" << std::endl;
19             return myStrategy->computeScore(a, len);
20         }
21         else
22         {
23             return 0;
24         }
25 
26     }
27 
28 };
29 
30 
31 int main()
32 {
33     Context *game = new Context();
34     double a[] = { 9.12, 9.25, 8.87, 9.99, 6.99, 7.88 };
35     int len = sizeof(a) / sizeof(double);
36 
37     game->setStrategy(new StrategyOne());
38     double r1 = game->getPersonScore(a,len);
39     std::cout << "strategy one: " << r1 << std::endl;
40 
41     game->setStrategy(new StrategyTwo());
42     double r2 = game->getPersonScore(a, len);
43     std::cout << "strategy two: " << r2 << std::endl;
44 
45     game->setStrategy(new StrategyThree());
46     double r3 = game->getPersonScore(a, len);
47     std::cout << "strategy three : " << r3 << std::endl;
48 
49     delete game;
50     game = NULL;
51 
52     return 0;
53 }
View Code

    在实现中,值得注意的是,设置具体的策略的时候,函数的形参是类的指针。然后本例子实现的是一个统计分数数组的平均分的不同策略,而C++中在数组作为参数的时候,实际上是退化为指针了,而这样是无法获取数组的长度的,所以

也传入了一个长度参数。

(三)策略模式-C++实现