策略模式:准备一组算法,并将每一个算法封装起来,使得它们可以互换。

1、策略模式中的角色与职责

    在策略模式中分为4个角色:环境类Context、具体环境类SubContext、策略类Stategy、具体策略类SubStrategy。

  • Context(环境类):环境类是一个抽象类,它通过属性成员m_pStrategy调用具体策略类里的函数,以实现不同功能。
  • SubContext(具体环境类、子环境类):继承环境类Context,实现对某个对象或环境的描写。
  • Strategy(策略类):是一个接口,里面有抽象的方法,这些抽象方法,需要SubStrategy去实现。
  • SubStrategy(具体策略类、子策略类):实现抽象策略类里的算法,在运行时,覆盖Strategy父对象,实现对某个具体业务的处理。
        如下:

图(1) 策略模式的UML类图

    Context环境类,是一个抽象类,它不仅仅可以代表上下左右的事物或场景,而且也可以代表某种生物,比如鸭子,它里面有3个函数:Flyed()、Quacked()、Display(),分别表示飞行、鸣叫、显示。鸭子分为很多种,有野鸭、红头鸭、道具鸭、模型鸭、橡皮鸭等,前2种有生命,后3种无生命,因此,野鸭、红头鸭、道具鸭等鸭属于子环境SubContext,鸭有翅膀,可以在水上飞、岸边飞、草场飞,这种飞行方式属于一种策略,因此放到Strategy接口里,然后再由具体策略类SubStrategy实现飞的方式。

    鸭子的鸣叫,有的是呱呱叫、有的是吱吱叫、还有的是嘎嘎叫等等,所以鸣叫也是一种策略,需要用接口来封装,然后再用子策略去实现。
    具体如下:

图(2) 飞行与鸣叫的策略模式

2、代码实现

2.1 飞行策略

    //FlyBahavior.h

#pragma once
#include <iostream>
using namespace std;//------------  1) 飞行行为的接口 -----------------------//
class FlyBehavior {public:virtual void Flyed() const = 0;virtual ~FlyBehavior() = default;
};class FlyNoWay : public FlyBehavior {public:void Flyed() const override {cout << "I can't fly!" << endl;}
};class FlyRocketPowered :public FlyBehavior {public:void Flyed() const override {cout << "I'm flying with a rocket" << endl;}
};class FlyWithWings :public FlyBehavior {public:virtual void Flyed() const override {cout << "I'm flying" << endl;}
};

2.2 鸣叫策略

    //QuackBehavior.h

#pragma once
#include <iostream>
using namespace std;//----------------- 2) 鸣叫行为的接口 -----------------//
class QuackBehavior {public:virtual void Quacked() const = 0;virtual ~QuackBehavior() = default;
};class Quack :public QuackBehavior {public:void Quacked() const override {cout << "Quack" << endl;}
};class MuteQuack :public QuackBehavior {public:void Quacked() const override {cout << "Silence" << endl;}
};class Squeak : public QuackBehavior {public:void Quacked() const override {cout << "Squeak" << endl;}
};

2.3 鸭子类

    //Duck.h

#pragma once
#include <iostream>
#include <memory>
#include "FlyBehavior.h"
#include "QuackBehavior.h"using namespace std;//--------------- 3) 鸭子类 --------------------//
class Duck {public:std::unique_ptr<FlyBehavior>   m_pFlyBehavior;std::unique_ptr<QuackBehavior> m_pQuackBehavior;Duck(std::unique_ptr<FlyBehavior> pFlyed, std::unique_ptr<QuackBehavior> pQuack):m_pFlyBehavior(std::move(pFlyed)), m_pQuackBehavior(std::move(pQuack)){};virtual ~Duck() = default;virtual void Display() const = 0;void Quacked() const {m_pQuackBehavior->Quacked();}void Flyed() const {m_pFlyBehavior->Flyed();}void Swim() const {cout << "All ducks float,even decoys" << endl;}};//--------------- 3.2) 道具鸭 --------------------//
class DecoyDuck :public Duck {public:DecoyDuck():Duck(std::make_unique<FlyNoWay>(), std::make_unique<MuteQuack>()){}void Display() const override {cout << "Decoy Duck" << endl;}
};//--------------- 3.3) 野鸭 --------------------//
class MallardDuck :public Duck {public:MallardDuck():Duck(std::make_unique<FlyWithWings>(), std::make_unique<Quack>()){}void Display() const override {cout << "Mallard Duck" << endl;}
};//--------------- 3.4) 模型鸭 --------------------//
class ModelDuck :public Duck {public:ModelDuck(): Duck(std::make_unique<FlyWithWings>(), std::make_unique<Quack>()){}void Display() const override {cout << "Model Duck" << endl;}
};//--------------- 3.5) 红头鸭 --------------------//
class RedHeadDuck :public Duck {public:RedHeadDuck():Duck(std::make_unique<FlyWithWings>(), std::make_unique<Quack>()){}void Display() const override {cout << "Red Head Duck" << endl;}
};//--------------- 3.6) 橡皮鸭 --------------------//
class RubberDuck :public Duck {public:RubberDuck(): Duck(std::make_unique<FlyNoWay>(), std::make_unique<Squeak>()){}void Display() const override {cout << "Rubber Duck" << endl;}
};

2.4 主入口

    //main.cpp

#include "FlyBehavior.h"
#include "QuackBehavior.h"
#include "Duck.h"int main()
{MallardDuck mallard;mallard.Display();mallard.Swim();mallard.Quacked();mallard.Flyed();cout << "--------------- Mallard -----\n" << endl;RubberDuck rubberDuckie;rubberDuckie.Display();rubberDuckie.Swim();rubberDuckie.Quacked();rubberDuckie.Flyed();system("pause");return 0;
}

    效果如下:

图(3)策略模式的运行结果

3、策略模式的优缺点

3.1 优点

  • 策略模式提供了对“开闭原则”的完美支持,用户可以在不修改原有系统的基础上选择算法或行为,也可以灵活地增加新的算法或行为。
  • 使用策略模式可以避免多重条件选择语句。多重条件选择语句不易维护,它把采取哪一种算法或行为的逻辑,与算法或行为本身的实现逻辑混合在一起,将它们全部硬编码(Hard Coding)在一个庞大的多重条件选择语句中,比直接继承环境类的办法还要原始和落后。
  • 策略模式提供了一种算法的复用机制。由于将算法单独提取出来封装在策略类中,因此不同的环境类可以方便地复用这些策略类。

3.2 缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法。换言之,策略模式只适用于客户端知道所有的算法或行为的情况,客户端的权限太大。
  • 策略模式将造成系统产生很多具体策略类,任何细小的变化都将导致系统要增加一个新的具体策略类,会造成文件夹中class类个数的暴增。

C++ 策略模式的具体案例与优缺点相关推荐

  1. 【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

    文章目录 一.策略模式简介 二.策略模式适用场景 三.策略模式优缺点 四.策略模式与其它设计模式 五.策略模式代码示例 1.促销策略接口 2.满减促销策略 3.返现促销策略 4.空促销策略 5.促销策 ...

  2. 设计模式——策略模式

    目录 策略模式 引例 策略模式 策略模式的使用场景 优缺点 优点 缺点 策略模式的本质 策略与工厂结合 策略模式 策略模式与简单工厂类似,针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而 ...

  3. 策略模式总结,适用场景,优缺点,代码示例

    策略模式总结,适用场景,优缺点,代码示例 1.简介 1.1 继承带来的扩展和复用问题 1.2 进一步改进,利用接口 1.3 进一步改进,策略模式 2.适用场景 3.优点 4.缺点 5.代码示例 6.源 ...

  4. 什么是策略模式?策略模式的使用场景以及优缺点?

    策略模式 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变 ...

  5. 设计模式之策略模式(Strategy)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. 这可能是把策略模式讲的最通俗易懂得文章了!

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 本文转载自微信公众号:漫话编程  周末无事,窝在家里面看<权力的游戏第八季>,看的 ...

  7. Python设计模式-策略模式

    Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...

  8. Java设计模式之策略模式与状态模式

    一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...

  9. 设计模式之策略模式学习笔记

    前言 我想大家都加班写过"业务代码",一大堆的if else,甚至if里面套if-代码不得已变得十分臃肿,对应的维护成本也有所增加.而策略模式,就是为了解决违反了开放封闭原则的这一 ...

最新文章

  1. 学python需要英语基础吗-英语基础一般,如何才能学习C语言编程和Python
  2. 2-数组中重复的数字
  3. RabbitMQ操作代码封装
  4. linux目录变成只读,解决Linux文件系统变成只读的方法
  5. 任正非给华为代表处CFO定位:能力不够的赶快补
  6. php ajax实现上移,jquery实现标签上移、下移、置顶_jquery
  7. python中构造函数可以重载吗_python中的函数重载了吗?
  8. loadrunner性能测试步骤_性能测试LoadRunner操作流程之一
  9. python pdf编辑器开发_使用pymupdf开发pdf查看编辑器
  10. MAC安装中文输入法Rime
  11. 3.1 人工智能定义
  12. 倍福--232/485通信
  13. Centos/Debian 占用CPU100%挖矿病毒清理
  14. GC_CONCURRENT freed 循环不停打印日志
  15. java学习之破壳hello world
  16. 【Leetcode】19. Remove Nth Node From End of List (cpp)
  17. C++学习课件(三)
  18. 详细介绍Android中Parcelable的原理和使用方法
  19. 20xx绿色水墨创意学术报告PPT模版素材
  20. 科创板|柏楚电子披露网上中签结果 中签号码共19076个

热门文章

  1. Excel密码保护破解代码
  2. Btree 数据结构
  3. Windows11之Dev-C++超详细下载安装与使用教程
  4. 【操作系统】进程同步实验
  5. 排序算法之归并排序及Java实现
  6. 有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?用循环嵌套结构完成。(数字组合)
  7. 电力英语及计算机成绩查询入口官网,考试成绩查询入口
  8. 最新在Anaconda环境下安装pytorch以及cuda!!!
  9. Windows用户的分类
  10. 初学pwn-攻防世界(get_shell)