C++ 策略模式的具体案例与优缺点
策略模式:准备一组算法,并将每一个算法封装起来,使得它们可以互换。
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.促销策略接口 2.满减促销策略 3.返现促销策略 4.空促销策略 5.促销策 ...
- 设计模式——策略模式
目录 策略模式 引例 策略模式 策略模式的使用场景 优缺点 优点 缺点 策略模式的本质 策略与工厂结合 策略模式 策略模式与简单工厂类似,针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而 ...
- 策略模式总结,适用场景,优缺点,代码示例
策略模式总结,适用场景,优缺点,代码示例 1.简介 1.1 继承带来的扩展和复用问题 1.2 进一步改进,利用接口 1.3 进一步改进,策略模式 2.适用场景 3.优点 4.缺点 5.代码示例 6.源 ...
- 什么是策略模式?策略模式的使用场景以及优缺点?
策略模式 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变 ...
- 设计模式之策略模式(Strategy)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 这可能是把策略模式讲的最通俗易懂得文章了!
点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 本文转载自微信公众号:漫话编程  周末无事,窝在家里面看<权力的游戏第八季>,看的 ...
- Python设计模式-策略模式
Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...
- Java设计模式之策略模式与状态模式
一.策略模式定义 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们之间可以相互替换,策略模式可以在不影响客户端的情况下发生变化. 好了,定义看看就完了,我知道你很烦看定义. 二.策 ...
- 设计模式之策略模式学习笔记
前言 我想大家都加班写过"业务代码",一大堆的if else,甚至if里面套if-代码不得已变得十分臃肿,对应的维护成本也有所增加.而策略模式,就是为了解决违反了开放封闭原则的这一 ...
最新文章
- 学python需要英语基础吗-英语基础一般,如何才能学习C语言编程和Python
- 2-数组中重复的数字
- RabbitMQ操作代码封装
- linux目录变成只读,解决Linux文件系统变成只读的方法
- 任正非给华为代表处CFO定位:能力不够的赶快补
- php ajax实现上移,jquery实现标签上移、下移、置顶_jquery
- python中构造函数可以重载吗_python中的函数重载了吗?
- loadrunner性能测试步骤_性能测试LoadRunner操作流程之一
- python pdf编辑器开发_使用pymupdf开发pdf查看编辑器
- MAC安装中文输入法Rime
- 3.1 人工智能定义
- 倍福--232/485通信
- Centos/Debian 占用CPU100%挖矿病毒清理
- GC_CONCURRENT freed 循环不停打印日志
- java学习之破壳hello world
- 【Leetcode】19. Remove Nth Node From End of List (cpp)
- C++学习课件(三)
- 详细介绍Android中Parcelable的原理和使用方法
- 20xx绿色水墨创意学术报告PPT模版素材
- 科创板|柏楚电子披露网上中签结果 中签号码共19076个