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种设计模式——策略模式组件协作的主要内容,如果未能解决你的问题,请参考以下文章

23种设计模式——观察者模式组件协作

java23种设计模式之一: 策略模式

Java设计模式之策略模式

对复合(协作)算法/策略的封装方法——装饰模式总结

设计模式—“组件协作”

C++设计模式