23种设计模式——策略模式组件协作
Posted J-A
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了23种设计模式——策略模式组件协作相关的知识,希望对你有一定的参考价值。
文章目录
亦称:Strategy
意图
定义了一组策略,分别在不同类中封装起来,每种策略都可以根据当前场景相互替换,从而使策略的变化可以独立于操作者。比如我们要去某个地方,会根据距离的不同(或者是根据手头经济状况)来选择不同的出行方式(共享单车、坐公交、滴滴打车等等),这些出行方式即不同的策略。
什么时候使用策略
主要解决在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
- 针对同一问题的多种处理方式,仅仅是具体行为有差别时;
- 需要安全地封装多种同一类型的操作时;
- 同一抽象类有多个子类,而客户端需要使用if-else 或者 switch-case 来选择具体子类时
真实世界类比
假如你需要前往机场。 你可以选择乘坐公共汽车、 预约出租车或骑自行车。 这些就是你的出行策略。 你可以根据预算或时间等因素来选择其中一种策略。
策略模式的实现
1、抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
2、具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
3、环境(Context)类:持有一个策略类的引用,最终给客户端调用。
class Strategy
public:
virtual ~Strategy() = default;
virtual std::string DoAlgorithm(std::string strViewData) const = 0;
;
/**
* The Context defines the interface of interest to clients.
*/
class Context
/**
* @var Strategy The Context maintains a reference to one of the Strategy
* objects. The Context does not know the concrete class of a strategy. It
* should work with all strategies via the Strategy interface.
*/
private:
std::unique_ptr<Strategy> strategy_;
/**
* Usually, the Context accepts a strategy through the constructor, but also
* provides a setter to change it at runtime.
*/
public:
explicit Context(std::unique_ptr<Strategy> &&strategy = ) : strategy_(std::move(strategy))
/**
* Usually, the Context allows replacing a Strategy object at runtime.
*/
void SetStrategy(std::unique_ptr<Strategy> &&strategy)
strategy_ = std::move(strategy);
/**
* The Context delegates some work to the Strategy object instead of
* implementing +multiple versions of the algorithm on its own.
*/
void DoSomeBusinessLogic() const
if (strategy_)
std::cout << "Context: Sorting data using the strategy (not sure how it'll do it)\\n";
std::string strResult = strategy_->DoAlgorithm("aecbd");
std::cout << strResult << "\\n";
else
std::cout << "Context: Strategy isn't set\\n";
;
/**
* Concrete Strategies implement the algorithm while following the base Strategy
* interface. The interface makes them interchangeable in the Context.
*/
class ConcreteStrategyA :public Strategy
public:
std::string DoAlgorithm(std::string strViewData) const override
std::string strResult(strViewData);
std::sort(std::begin(strResult), std::end(strResult));
return strResult;
;
class ConcreteStrategyB :public Strategy
public:
std::string DoAlgorithm(std::string strViewData) const override
std::string strResult(strViewData);
std::sort(std::begin(strResult), std::end(strResult), std::greater<>());
return strResult;
;
策略模式的优缺点
优点 | 缺点 |
---|---|
你可以在运行时切换对象内的算法。 | 如果你的算法极少发生改变, 那么没有任何理由引入新的类和接口。 使用该模式只会让程序过于复杂。 |
你可以将算法的实现和使用算法的代码隔离开来。 | 客户端必须知晓策略间的不同——它需要选择合适的策略。 |
你可以使用组合来代替继承。 | 许多现代编程语言支持函数类型功能, 允许你在一组匿名函数中实现不同版本的算法。 这样, 你使用这些函数的方式就和使用策略对象时完全相同, 无需借助额外的类和接口来保持代码简洁。 |
开闭原则。 你无需对上下文进行修改就能够引入新的策略。 |
以上是关于23种设计模式——策略模式组件协作的主要内容,如果未能解决你的问题,请参考以下文章