(三)策略模式-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

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 }

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 }

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

也传入了一个长度参数。

时间: 2024-12-13 05:30:09

(三)策略模式-C++实现的相关文章

Javascript模式(三) 策略模式

var data = { "username" : "zhangsan", "password" : "12345690", "code" : "abcd" }; var validate = { rules : {}, config : {}, msg : [], check : function(data){ var k, rule, config, checker; rule =

计算器软件的代码实现 (windowform窗体+SQL+策略模式)

一 整体概述 这个计算器软件的功能和以前的功能基本上一样,只不过是数据的保存形式发生了变化,,以前用的是txt文件保存,现在更正用SQL数据库,现在更改了以前的文件保存形式,是三层架构中数据层的更换,但是仍然采用了设计模式中的策略模式,对于在wpf中实现的要求,会在今后中进一步实现的! 二 数据库代码的封装  using System; using System.Collections.Generic; using System.Linq; using System.Text; using Sy

设计模式---策略模式Strategy Pattern

策略模式 定义:定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化. 问题:有一个鸭子类定义了鸭子的种种行为,包括swim(),quack(),fly(),但是,并不是所有的鸭子都会飞行(fly)或者叫(quack),在这里,我们认为所有的鸭子都会浮在水面上(swim).如何实现各种不同的鸭子的不同的表现. 解决方法:第一个想到的会使继承,在鸭子父类中定义好所有的方法,在实现鸭子子类的过程中,对不满足于具体的鸭子的行为进行覆盖,但是在这种方法

策略模式,我与你的三次相遇。

从商场打折到机房重构计算固定用户和临时用户的消费情况,再到现在的Duck,三次接触类策略模式,可见这是一个比较重要的模式. 在使用策略模式之前,首先要知道什么是策略模式?策略模式是干吗用的?策略模式有它的好处也必定存在一定的缺陷. 策略模式: 它定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式其实就是用来封装算法的.当不同的行为堆砌在一个类中,就很难避免使用条件语句来选择合适的行为.我们就可以用策略模式,将这些行为封装在一个个独立的Stra

Javascript设计模式学习三(策略模式)

定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == 'B'){ return 2; } if(input == 'C'){ return 3; } //或者 switch(input){ case 'A': console.log(1); break; case 'B': console.log(2); break; case 'C': conso

(三)设计模式之PHP项目应用(策略模式:商场收银系统)

1 策略模式简介 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 2 模式组成 1)抽象策略角色(Strategy): 策略类,通常由一个接口或者抽象类实现. 2)具体策略角色(ConcreteStrategy): 包装了相关的算法和行为. 3)环境角色(Context): 持有一个策略类的引用,最终给客户端调用. 3 模式核心思想 策略模式是一种定义一些列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是

三分钟理解“策略模式”——设计模式轻松掌握

实际问题: 由于超市隔三差五就要办促销活动,但每次促销活动的方式不一样,所以需要开发一个软件,营业员只要输入原价再选择活动类型后,就能计算出折扣以后的价钱. 普通人的做法: mian(){ String input = readLine(); double price = readLine(); switch (input) case "九五折": price = price * 0.95; break; case "满100返50": if(price>=1

设计模式之策略模式

一.概述我们来实现一个企业的工资系统,该企业中不同级别的员工工资算法都不相同,针对该问题,最容易想到的莫过于在代码中堆积一大堆if…else…语句或者是switch…case…语句.如果该企业中不同级别的员工过多,或是对级别的调整比较频繁,那该系统就会显得复杂而脆弱.如何能将对象和算法解耦,从而使得在系统运行时能透明的改变对象的算法呢?这就到了策略模式大显身手的时候了.二.策略模式策略模式定义了一系列算法,把它们一个个封装起来,并且使它们可相互替换.该模式可使得算法能独立于使用它的客户而变化.策

Strategy Design Pattern(策略模式)

策略模式意义在于,当我们有多种不同的算法时,程序能够动态的选择算法进行计算. 策略模式的另外一个英文名字是Policy Strategy. 策略模式最典型的里一个例子就是JAVA中复杂对象的排序(java.util.Arrays.sort,java.util.Collections.sort),用户可以自己定义各种排序算法(规则),然后在需要排序时将算法传给排序函数.从而实现排序方式的变化,获得不同的排序结果.参见:http://my.oschina.net/nox/blog/487478 下面