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

三种角色:

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

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

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

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

1、strategy.h

 #ifndef _STRATEGY_H_
#define _STRATEGY_H_ //抽象策略类
class ComputeStrategy{
public:
//这里参数是a[] 实际上相当于指针 所以想获取其长度 非常困难(应该获取不了) 所以传入一个个数
virtual double computeScore(double a[], int len) = ;
}; //具体策略类
class StrategyOne : public ComputeStrategy
{
public:
double computeScore(double a[], int len);
}; class StrategyTwo : public ComputeStrategy
{
public:
double computeScore(double a[], int len);
}; class StrategyThree : public ComputeStrategy
{
public:
double computeScore(double a[], int len);
}; #endif

2、strategy.cpp

 #include "strategy.h"
#include <iostream>
#include <cmath>
#include <algorithm> double StrategyOne::computeScore(double a[], int len)
{
double score = , sum = ;
for (int i = ; i < len; i++)
{
sum += a[i];
}
score = sum / len;
return score;
} double StrategyTwo::computeScore(double a[], int len)
{
double score = , multi = ;
for (int i = ; i < len; i++)
{
multi *= a[i];
}
score = std::pow(multi, 1.0 / len);
return score;
} double StrategyThree::computeScore(double a[], int len)
{
double score = , sum = ;
if ( >= len)
{
return 0.0;
} std::sort(a, a + len);
for (int i = ; i < len - ; i++)
{
sum += a[i];
}
score = sum / (len - );
return score; }

3、context.cpp

 #include <iostream>
#include "strategy.h" //上下文类 依赖策略类
class Context
{
public:
ComputeStrategy* myStrategy;
public:
void setStrategy(ComputeStrategy* strategy)
{
myStrategy = strategy;
}
double getPersonScore(double a[], int len)
{
if (NULL != myStrategy)
{
std::cout << "myStrategy not null" << std::endl;
return myStrategy->computeScore(a, len);
}
else
{
return ;
} } }; int main()
{
Context *game = new Context();
double a[] = { 9.12, 9.25, 8.87, 9.99, 6.99, 7.88 };
int len = sizeof(a) / sizeof(double); game->setStrategy(new StrategyOne());
double r1 = game->getPersonScore(a,len);
std::cout << "strategy one: " << r1 << std::endl; game->setStrategy(new StrategyTwo());
double r2 = game->getPersonScore(a, len);
std::cout << "strategy two: " << r2 << std::endl; game->setStrategy(new StrategyThree());
double r3 = game->getPersonScore(a, len);
std::cout << "strategy three : " << r3 << std::endl; delete game;
game = NULL; return ;
}

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

也传入了一个长度参数。

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

  1. Java设计模式从精通到入门三 策略模式

    介绍 我尽量用最少的语言解释总结: Java23种设计模式之一,属于行为型模式.一个类的行为或者算法可以在运行时更改,策略对象改变context对象执行算法. 应用实例: ​ 以周瑜赔了夫人又折兵的例 ...

  2. JS 设计模式三 -- 策略模式

    策略模式 概念 定义一系列算法,把它们一个个封装起来. 将算法的使用与算法的实现分离开来 实现 // 加权映射关系 var levelMap = { S: 10, A: 8, B: 6, C: 4 } ...

  3. Javascript模式(三) 策略模式

    var data = { "username" : "zhangsan", "password" : "12345690" ...

  4. 设计模式:HelloWorld之策略模式

    一.概述 策略模式 定义了算法族,分别封装起来,让他们可以互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式的三要素: 抽象策略角色: 策略类,通常由一个接口或者抽象类实现. 具体策略角色: ...

  5. 计算器软件实现系列(六)windowform窗体+SQL+策略模式

    一 整体概述 这个计算器软件的功能和以前的功能基本上一样,只不过是数据的保存形式发生了变化,,以前用的是txt文件保存,现在更正用SQL数据库,现在更改了以前的文件保存形式,是三层架构中数据层的更换, ...

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

    定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以互相替换.目的:将算法的使用和算法的实现分离开来.比如: if(input == 'A'){ return 1; } if(input == ...

  7. JAVA中的设计模式三(策略模式)

    问题: 如何让算法和对象分开来,使得算法可以独立于使用它的客户而变化?   方案: 把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就 ...

  8. 两种语言实现设计模式(C++和Java)(三:策略模式)

    策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法可独立于使用它的客户而变化.也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异.用策略模式 ...

  9. JavaScript设计模式(三) - 策略模式

    什么是策略模式? 策略模式支持在运行时由使用者选择合适的算法,对于使用者而言不用关心背后的具体实现,由使用者自动根据当前程序执行的上下文和配置,从已有的算法列列表中选择出合适的算法来处理当前任务.   ...

随机推荐

  1. Mondrian – 开源的矢量图形 Web 应用程序

    Mondrian 是一个免费矢量图形 Web 应用程序,类似 Adobe Illustrator 或 Inkscape.Mondrian 提供所有所需的工具来创建.修改和导出简单的 SVG 文件,过历 ...

  2. SAP 使用较频繁的日期时间处理函数总结

    在ABAP实际开发中,经常需要用到一些日期时间处理函数,个人感觉经常使用到的函数进行一下汇总 1.  根据工厂日历 计划交货日期 和 收货处理时间 来计算 销售计划中计划完工日期,其他类似日期计算等 ...

  3. Troubleshooting FIM: (No Display Name) in FIM Portal

    from: http://social.technet.microsoft.com/wiki/contents/articles/12682.troubleshooting-fim-no-displa ...

  4. CAShaperLayer的应用

    关于CAShapeLayer的一些实用案例和技巧 实现遮罩 音量大小动态改变的控件 圆形进度条 iOS 利用CAShapeLayer的FillRule属性生成一个空心遮罩的layer fillrule ...

  5. iOS关于启动页自定义特殊处理

    平常开发中对于启动页可能会有一些特别的要求,比如在启动页加动画或加一些按键可以响应事件等,最近项目中要在启动页增加版本号,因为版本号是不断的改变,所以要动态实现把它加到启动页上:在XCode上面配置的 ...

  6. Android Sqlite基本命令

    要查看数据库,首先必须要找到db文件,如果拷贝到电脑上,查看的方法比较多,在手机上,用命令查看比较直接和方便. 首先要找到数据库的位置,一般数据库时存放在程序的私有目录,所以要获取root权限. 确保 ...

  7. HTTP协议基本知识

    Xcode7.0以上版本必须操作:https http 在Info.plist中添加NSAppTransportSecurity类型Dictionary. 在NSAppTransportSecurit ...

  8. ARC下内存泄露问题

    ARC下内存泄露问题 ARC下内存泄露问题,有需要的朋友可以参考下. iOS提供了ARC功能,很大程度上简化了内存管理的代码. 但使用ARC并不代表了不会发生内存泄露,使用不当照样会发生内存泄露. 下 ...

  9. HashMap vs TreeMap vs Hashtable vs LinkedHashMap

    Map是一个重要的数据结构,本篇文章将介绍如何使用不同的Map,如HashMap,TreeMap,HashTable和LinkedHashMap. Map概览 Java中有四种常见的Map实现,Has ...

  10. 因GIT默认忽略.dll文件导致的Visual Studio项目通过Bamboo编译失败

    背景 由GIT管理的Visual Studio项目,使用Stash管理远端代码库,通过与Stash集成的Bamboo生成项目并发布 现象 Visual Studio项目本地生成成功,用SourceTr ...