DesignPatterns_Strategy

/////////////////////////////////////////////////////////////////////////////
// Strategy pattern
// - Define a family of algorithms, encapsulate each one, and make them
//   interchangeable. Strategy lets the algorithm vary independently from
//   clients that use it.
// - Code containing many conditional statements often indicates the need to
//   apply the Strategy pattern.
//
// Author     : ZAsia
// Date       : 15/05/17
// Warning    : In practice, declaration and implementation should
//              be separated(.h and .cpp).
//////////////////////////////////////////////////////////////////////////////
#include 
using namespace std;

// Strategy
// - declares an interface common to all supported algorithms. Context uses
//   this interface to call the algorithm defines by a ConcreteStrategy.
class Strategy
{
public:
	virtual void AlgorithmInterface() = 0;
};

// ConcreteStrategy
// - implements the algorithm using the Strategy interface.
class ConcreteStrategyA : public Strategy
{
public:
	virtual void AlgorithmInterface()
	{
		cout << "ConcreteStrategyA::AlgorithmInterface" << endl;
	}
};

class ConcreteStrategyB : public Strategy
{
public:
	virtual void AlgorithmInterface()
	{
		cout << "ConcreteStrategyB::AlgorithmInterface" << endl;
	}
};

class ConcreteStrategyC : public Strategy
{
public:
	virtual void AlgorithmInterface()
	{
		cout << "ConcreteStrategyC::AlgorithmInterface" << endl;
	}
};

// Context
// - is configured with a ConcreteStrategy object.
// - maintains a reference toa Strategy object.
// - may define an interface that lets Strategy access its data.
class Context
{
public:
	Context(Strategy *strategy) : _strategy(strategy) { }

	~Context() 
	{
		if (_strategy)
		{
			delete _strategy;
		}
	}

	void ContextInterface()
	{
		_strategy->AlgorithmInterface();
	}

private:
	Strategy *_strategy;
};

// collaborations
// - Strategy and Context interact to implement the chosen algorithm. A context
//   may pass all data required by the algorithm to the strategy when the algorithm
//   is called. Alternatively, the context can pass itself as an argument to Strategy
//   operations. That lets the strategy call back on the context as required.
// - A context frowards requests from its clients to its strategy. Clients usually
//   create and pass a ConcreteStratey object to the context; thereafter, clients 
//   interact with the context exclusively.  There is often a family of ConcreteStrategy
//   classes for a client to choose from.
int main()
{
	// here, i make Context responsible for free ConcreteStrategy.
	Context *pContextA = new Context(new ConcreteStrategyA());
	Context *pContextB = new Context(new ConcreteStrategyB());
	Context *pContextC = new Context(new ConcreteStrategyC());

	pContextA->ContextInterface();
	pContextB->ContextInterface();
	pContextC->ContextInterface();

	if (pContextA)
	{
		delete pContextA;
		pContextA = nullptr;
	}

	if (pContextB)
	{
		delete pContextB;
		pContextB = nullptr;
	}

	if (pContextC)
	{
		delete pContextC;
		pContextC = nullptr;
	}

	return 0;
}

////////////////////////////////////////////////////////////////
// 1.Clients must be aware of different Strategies. The pattern has a potential
//   drawback in that a client must understand how Strategies differ before it
//   can select the appropriate one.
發佈了110 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章