本文是设计模式的第二篇-策略模式(Strategy Pattern)。作为一个对自己写的内容负责的作者(不模仿,不抄袭,坚持自己深入理解后再写博客),本人参考了不下十篇同类型文章,但是看多了文章就会有些疑惑,策略模式和工厂模式的区别,为什么看起来没有什么区别。标题为深入理解策略模式,本文会深度解析策略模式的实际应用以及它的优点和缺点,达到足够深的地步!
文章开头先给大家介绍一下自己的策略模式和摘录的几篇策略模式文章的解释:
策略模式(Strategy Pattern)定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换。Strategy 可以使算法独立于使用算法的客户端。
策略模式是指定义一系列的算法,把它们单独封装起来,并且使它们可以互相替换,使得算法可以独立于使用它的客户端而变化,也是说这些算法所完成的功能类型是一样的,对外接口也是一样的,只是不同的策略为引起环境角色环境角色表现出不同的行为。
策略模式是指定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。也就是说这些算法所完成的功能一样,对外的接口一样,只是各自实现上存在差异。用策略模式来封装算法,效果比较好。
定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户端。
以上这些解释都来自不同博主的策略模式解释(都是Ctrl+c And Ctrl+v),本文要做的就是帮助大家更好的理解(深入的理解),提供有区别于他们的例子(与众不同的),让大家看完这篇博客之后不像有些博客一样还是处于朦朦胧胧的状态(一脸懵逼)!
本文作者原创,未经允许请勿转载,本帖原创请勿照抄。
设计模式中大部分模式中都很明显的体现出了封装、继承、多态的设计思想,作者本人其实在日常的编程中很少使用设计模式,但是封装、继承、多态是会随着编程从而时时刻刻都会接触到的东西。
在讲解策略模式的过程中,作者看到了鸭子图、缓存图、上下文图、动物图、角色图(这个作者一看就是经常打王者,分析的这么透彻)......等等...等等...
为什么会说上面这句话呢?因为作者也要按照这个套路创作一个已图为开始节点的策略模式,那就是中华文明的结晶!吃!
Have a Go To Meal Strategy Pattern!
C++ (2) 深入理解策略模式目录
一、策略模式(传统大众的写法)
#include "pch.h"
#include <iostream>
using namespace std;
//抽象接口
class ReplaceAlgorithm
{
public:
virtual void Replace() = 0;
};
//哪只手吃(三种具体的替换算法)
class LeftHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat with your left hand" << endl; }
};
class RightHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat with your right hand" << endl; }
};
class IsNoHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat without using your hands" << endl; }
};
//Meal 吃饭需要用到替换算法
enum RA { Left, Right, IsNo
}; //标签
class Meal
{
private:
ReplaceAlgorithm *m_ra;
public:
Meal(enum RA ra)
{
if (ra == Left)
m_ra = new LeftHand_ReplaceAlgorithm();
else if (ra == Right)
m_ra = new RightHand_ReplaceAlgorithm();
else if (ra == IsNo)
m_ra = new IsNoHand_ReplaceAlgorithm();
else
m_ra = NULL;
}
~Meal() { delete m_ra; }
void Replace() { m_ra->Replace(); }
};
int main()
{
Meal meal(IsNo); //指定标签即可
meal.Replace();
system("pause");
return 0;
}
二、策略模式(函数指针实现)
#include "pch.h"
#include <iostream>
using namespace std;
//抽象接口
class ReplaceAlgorithm
{
public:
virtual void Replace() = 0;
};
//哪只手吃(三种具体的替换算法)
class LeftHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat with your left hand" << endl; }
};
class RightHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat with your right hand" << endl; }
};
class IsNoHand_ReplaceAlgorithm : public ReplaceAlgorithm
{
public:
void Replace() { cout << "Eat without using your hands" << endl; }
};
//Meal 吃饭需要用到替换算法
enum RA { Left, Right, IsNo
}; //标签
class Meal
{
private:
ReplaceAlgorithm *m_ra;
public:
Meal(enum RA ra)
{
if (ra == Left)
m_ra = new LeftHand_ReplaceAlgorithm();
else if (ra == Right)
m_ra = new RightHand_ReplaceAlgorithm();
else if (ra == IsNo)
m_ra = new IsNoHand_ReplaceAlgorithm();
else
m_ra = NULL;
}
~Meal() { delete m_ra; }
void Replace() { m_ra->Replace(); }
};
int main()
{
Meal* meal = new Meal(IsNo);//指定标签
meal->Replace();
delete meal;
meal = nullptr;
system("pause");
return 0;
}
三、多样化策略模式
这个其实和工厂模式类似,都是一种产品线对应产品的关系,代码就不写了这里写代码意义不太大,可以参考上面的代码脑补一下。
四、策略模式的总结
1. 优点
相比于使用大量的if...else,使用策略模式可以降低复杂度,使得代码更容易维护。
提供了一种替代继承的方法,而且既保持了继承的优点(代码重用)还比继承更灵活(算法独立,可以任意扩展)。
避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展。
遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。
2. 缺点
可能需要定义大量的策略类,并且这些策略类都要提供给客户端。
因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量。
3. 区别
工厂模式是为了创建对象,用多态实现。
策略模式是为了对同一方法有不同的实现,用多态实现。
4. 应用场景
多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
对客户(Duck)隐藏具体策略(算法)的实现细节,彼此完全独立。
5. 其它
在看好多文章的时候产生了似曾相识的感觉,感觉和工厂模式有点像,但是它们的解决场景又不太一样。
在我看完第4点,应用场景后相信大家会对这些产生理解,拨开云雾见到了太阳。
最后文章写到这里又要告一段落了,最近可能会把重心放在自绘、二三维、和设计模式上面,有兴趣的小伙伴可以点点关注,一起期待,同时文章中有什么疑问或者不清楚的地方也可以在下方评论区留言,看到了会及时回复的~
参考文章:https://www.cnblogs.com/justinw/archive/2007/02/06/641414.html
参考文章:https://blog.csdn.net/wuzhekai1985/article/details/6665197