1、策略模式(strategy)
1)定义
定义了算法家族,分别封装起来,让他们之间可以互相转换,此模式让算法的变化不会影响到使用算法的客户。属于行为型模式。
2)适用场景
> 如果一个对象有多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,则在使用的过程中,可以通过switch语句并通过传入type的方式进行调用。
> 一个类需要动态地选择几种算法中的一种;
> 算法使用了客户不应该知道的数据或者结构,避免暴露复杂的算法逻辑和数据结构;
3)优缺点
优点:通过基类抽象,将不同的算法进行封装,利于算法的扩展和独立性;
缺点:当算法不断扩展时,context中需要进行相应变动,同时使用者需要连接各个算法的具体功能,同时会造成类膨胀的问题;
4)UML类图
AbstractStrategy:策略类,定义支持所有算法的公共接口;
StrategyA..C:具体的算法或行为,继承自AbstractStrategy;
Context:context上下文,维护一个AbstractStrategy对象,内部通过传入不同的type,来确定使用哪种算法;
4)代码实现
#include<iostream>
#include<memory>
using namespace std;
enum class Type : uint32_t
{
KStrategyA = 1,
KStrategyB = 2,
KStrategyC = 3
};
// 抽象算法类
class AbstractStrategy
{
public:
// 算法方法
virtual void Algorithm() = 0;
};
// 具体算法A
class StrategyA : public AbstractStrategy
{
public:
void Algorithm() override
{
cout << "* Algorithm StrategyA *" << endl;
}
};
// 具体算法B
class StrategyB : public AbstractStrategy
{
public:
void Algorithm() override
{
cout << "* Algorithm StrategyB *" << endl;
}
};
// 具体算法C
class StrategyC : public AbstractStrategy
{
public:
void Algorithm() override
{
cout << "* Algorithm StrategyC *" << endl;
}
};
class Context
{
public:
// 通过传入不同的type,生成不同的算法
void DisplayAlgorithm(Type type)
{
switch (type)
{
case Type::KStrategyA:
ptr_abs_strategy_ = std::make_unique<StrategyA>();
break;
case Type::KStrategyB:
ptr_abs_strategy_ = std::make_unique<StrategyB>();
break;
case Type::KStrategyC:
ptr_abs_strategy_ = std::make_unique<StrategyC>();
break;
default:
cout << "* Unknown data type *" << endl;
break;
}
ptr_abs_strategy_->Algorithm();
}
private:
std::unique_ptr<AbstractStrategy> ptr_abs_strategy_;
};
int main()
{
Context context;
context.DisplayAlgorithm(Type::KStrategyA);
context.DisplayAlgorithm(Type::KStrategyB);
context.DisplayAlgorithm(Type::KStrategyC);
system("pause");
return 0;
}