C++设计模式浅识策略模式

策略模式定义: 

定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。 

策略模式包含如下角色:

context:环境类

strategy:抽象策略类

concretestrategy: 具体策略类

uml类图: 

341.jpg

测试用例

[code]int main(){    //商品费用    double cost;    //采取某种收费策略之后的费用    double result;    //假如    cost = 1029.88;    //声明要使用的具体策略类    //这里显示出了策略类的缺点:客户端必须知道有哪些具体封装的算法。如本例必须知道三种收费方式Normal、Return、Rebate。    StrategyCashSuper *Normal = new ConerectStrategyNormal(cost);//抽象策略类(基类)指针指向派生类->具体策略类(普通收费方式)    StrategyCashSuper *Return = new ConerectStrategyReturn(cost); //满300返100收费方式    StrategyCashSuper *Rebate = new ConerectStrategyRebate(cost); //打八折收费    //声明环境类,具体调用的算法,由它来维护    Context *c = new Context();    //设置使用的策略类    c->setStrategy(Normal);//设置为普通收费    //调用算法    result = c->getChargeResult();    std::cout << "Accrued expenses: " << result <setStrategy(Return);//设置为满300返100收费方式    //调用算法    result = c->getChargeResult();    std::cout << "Accrued expenses: " << result <setStrategy(Rebate);//设置为打八折收费    //调用算法    result = c->getChargeResult();    std::cout << "Accrued expenses: " << result << std::endl;    return 0;}

头文件Strategy.h

[code]#ifndef _2STRATEGY_H_#define _2STRATEGY_H_//策略类,算法基类class StrategyCashSuper{protected:    //商品应付费用,定义为保护成员供子类继承    double cost;   public:    //构造函数    StrategyCashSuper(double c):cost(c){}    //收费结果算法    virtual double ChargeResult();//本想定义为纯虚函数,但不可以。因为虚基类本不能实例化};//正常收费算法class ConerectStrategyNormal: public StrategyCashSuper{public:    //构造函数    ConerectStrategyNormal(double c):StrategyCashSuper(c){}    //根据本类的收费方式,重写继承的收费算法    double ChargeResult()override;};//满300返100收费算法class ConerectStrategyReturn: public StrategyCashSuper{public:    //构造函数    ConerectStrategyReturn(double c):StrategyCashSuper(c){}    //重写收费算法    double ChargeResult()override;    };//打八折收费算法class ConerectStrategyRebate: public StrategyCashSuper{public:    //构造函数    ConerectStrategyRebate(double c):StrategyCashSuper(c){}    //重写收费算法    double ChargeResult()override;  };//环境类,根据具体算法,维护上下文使用的类class Context{private:    //策略基类    StrategyCashSuper *SCS;public:    //设置使用的策略    void setStrategy(StrategyCashSuper *s);    //具体执行的算法    double getChargeResult();};#endif

实现Strategy.cpp

立即学习“C++免费学习笔记(深入)”;

[code]#include "2Strategy.h"//基类double StrategyCashSuper::ChargeResult(){    return 0;}//正常收费double ConerectStrategyNormal::ChargeResult(){    return cost;}//满300返100收费算法double ConerectStrategyReturn::ChargeResult(){    double res = cost;    if(res >= 300)        res = cost - 100;    return res;}//打八折收费算法double ConerectStrategyRebate::ChargeResult(){    return cost *0.8;}//设置使用的算法void Context::setStrategy(StrategyCashSuper *s){    SCS = s;}//具体执行的算法double Context::getChargeResult(){    return SCS->ChargeResult();}

总结:

策略模式让算法独立于使用它的客户而变化,也成为政策模式。策略模式是一种对象行为型模式。

策略模式包含3个角色:抽象策略类为所支持的算法声明了抽象方法,是所有策略类的父类;具体策略类实现了在抽象策略类中定义的算法。环境类在解决某个问题时可以采用多种策略类(缺点是客户端需要知道所有封装的策略类),在环境类中维护一个对抽象策略类的引用实例。

策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。

策略模式主要优点在于对“开闭原则”的完美支持,在不修改原有系统的基础上可以更换算法或者增加新的算法,它很好的管理算法家族,提高了代码的复用性,是一种替换继承,避免多重条件转移语句的实现方式;其缺点在于客户端必须知道所有的策略类,并理解其区别,同时在一定程度上增加了系统中类的个数,可能会存在很多策略类。

策略模式适用情况包括:在一个系统里面有许多类,它们之间的区别仅在于它们的行为,使用策略模式可以动态地让一个对象在许多行为中选择一种行为;一个系统需要动态地在几种算法中选择一种;避免使用难以维护的多重条件选择语句;希望在具体策略类中封装算法和与之相关的数据结构。

以上就是C++设计模式浅识策略模式的内容,更多相关内容请关注PHP中文网(www.php.cn)!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1431951.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月17日 05:57:50
下一篇 2025年12月13日 20:50:05

相关推荐

  • C++设计模式浅识单例模式

    什么是单例模式?  保证一个类只有一个实例,并提供一个访问它的全局访问点。【dp】  让类的自身负责保存它的唯一实例,这个类保证没有其他实例可以被创建,并且此类可以提供一个访问该实例的方法。【dp】  什么时候需要单例模式?  程序只需要一个方法控制某项功能,不允许创建第二个此功能。比如:银行使用的…

    好文分享 2025年12月17日
    000
  • C#中OpenFileDialog和PictrueBox的用法分析

    本文实例讲述了c#中openfiledialog和pictruebox的用法。分享给大家供大家参考。具体用法分析如下: 先来看看这段代码: string resultFile = “”;OpenFileDialog openFileDialog1 = new OpenFileDialog();ope…

    好文分享 2025年12月17日
    000
  • C#中的switch case使用介绍

    在c#中  switch(type) { case tpye1: break; case tpye2: break; case tpye3: break; case tpye4: break; }; 其中type可以是数字,也可以是字符串;  以上就是C#中的switch case使用介绍的内容,更…

    2025年12月17日
    000
  • C# 判断两张图片是否一致的快速方法

    c# 判断两张图片是否一致的快速方法 #region 判断图片是否一致 /// /// 判断图片是否一致 /// /// 图片一 /// 图片二 /// 是否一致 public bool IsSameImg(Bitmap img, Bitmap bmp) { //大小一致 if (img.Width…

    好文分享 2025年12月17日
    000
  • C# web api返回类型设置为json的两种方法

    web api写api接口时默认返回的是把你的对象序列化后以xml形式返回,那么怎样才能让其返回为json呢,下面就介绍两种方法: 方法一:(改配置法)  找到global.asax文件,在application_start()方法中添加一句:  GlobalConfiguration.Config…

    好文分享 2025年12月17日
    000
  • c#生成缩略图不失真的方法实例分享

    c#生成缩略图不失真的方法实例分享 /// /// 获得缩微图/// /// public bool GetThumbImg(){try{string imgpath; //原始路径 if(imgsourceurl.IndexOf(“\”,0)<0) //使用的是相对路径 {imgpath =…

    好文分享 2025年12月17日
    000
  • c#将Excel数据导入到数据库的实现代码

    c#将excel数据导入到数据库的实现代码 假如Excel中的数据如下: 数据库建表如下: 其中Id为自增字段: 代码: using System;using System.Collections.Generic;using System.Linq;using System.Web;using Sy…

    2025年12月17日 好文分享
    000
  • C#实现上传照片到物理路径,并且将地址保存到数据库的小例子

    c#实现上传照片到物理路径,并且将地址保存到数据库的小例子 效果: 思路:首先,获取图片物理地址,然后进行判断将图片保存到文件夹下,再将图片的信息保存到数据库。数据库: create table image1 ( ID int identity(1,1) primary key, ImageName…

    2025年12月17日
    000
  • C#中的FileUpload 选择后的预览效果具体实现

    c#中的fileupload 选择后的预览效果  实现方法:  HTML:  JS:  function onFileChange(sender) { document.getElementById(“imgDimensionalPic”).src = window.URL.createObject…

    2025年12月17日
    000
  • c#加密类使用方法示例

    c#加密类使用方法示例 using System;using System.IO;using System.Text;using System.Security.Cryptography;using System.Web;namespace Encryption.App_Code{ /// /// …

    好文分享 2025年12月17日
    000
  • C#操作Excel数据增删改查示例

    c#操作excel数据增删改查。  首先创建exceldb.xlsx文件,并添加两张工作表。  工作表1:  userinfo表,字段:userid、username、age、address、createtime。  工作表2:  order表,字段:orderno、productname、quan…

    好文分享 2025年12月17日
    000
  • 通过C#动态生成图书信息XML文件

    通过c#动态生成图书信息xml文件(books.xml),文件如下:  Harry Potter J K. Rowling 2005-08-15 29.99 Learning XML Erik T. Ray 2003-10-18 39.95 方法1:使用StringBuilder拼接XML  ///…

    好文分享 2025年12月17日
    000
  • C#获取当前页面的URL示例代码

    本实例的测试url:http://www.mystudy.cn/web/index.aspx  1、通过c#获取当前页面的url  string url = Request.Url.AbsoluteUri; //结果: http://www.mystudy.cn/web/index.aspx str…

    好文分享 2025年12月17日
    000
  • C++设计模式浅识装饰模式

    装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活。  装饰模式的四个角色: 组件类:component 具体组件类:coneretecomponent 装饰类:decorator(从外类来扩展component类的功能,但对于component来说是无需知道d…

    好文分享 2025年12月17日
    000
  • C++设计模式浅识迭代器模式

    迭代器模式:提供一中方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。【dp】 四个角色: iterator迭代器抽象类: 用于定义得到开始对象,得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口。 concreteiterator具体迭代器类: 继承iterator,实现…

    好文分享 2025年12月17日
    000
  • C++设计模式浅识外观模式

    外观模式(facade):为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 两大角色: 外观类facade: 知道哪些子系统类负责处理请求,将客户的请求代理给适当的子系统对象。 子系统集合subsystem: 实现子系统的功能,处理facade对…

    好文分享 2025年12月17日
    000
  • C++设计模式浅识模板方法模式

    模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 适用的一个时机:当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。 模板方…

    2025年12月17日
    000
  • C++设计模式浅识原型模式

    定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式其实就是从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。 原型模式主要考虑的深复制与浅复制,在c++++的类设计中,拷贝构造函数就是浅复制,当重载赋值运算符时就是深复制。 浅复制:被复制对象的所有变量…

    好文分享 2025年12月17日
    000
  • C++设计模式浅识工厂方法模式

    工厂方法模式(factory method):定义一个用于创建对象的接口,让子类去实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。 与简单工厂的区别:简单工厂需要修改原有类,违背了开闭原则。而工厂方法就避免类这个问题。保持了封装对象的创建过程的优点,只需增加工厂类就可以,解决了简单工厂分支判断…

    2025年12月17日
    000
  • C++设计模式浅识代理模式

    代理模式(proxy): 为其他对象提供一种代理以控制对这个对象(被代理者,即本人)的访问。  在c++#中实现方法是使用接口interface定义需要的方法,而在c++中需要实现一个类作为接口使用,其中定义需要的方法。这样对我话,本人并不需要参与其中的具体活动,而由代理人出面。客户端(第三方)也不…

    好文分享 2025年12月17日
    000

发表回复

登录后才能评论
关注微信