首页 > 代码库 > 设计模式(二):策略模式

设计模式(二):策略模式

简单工厂模式是客户告诉工厂所需要的对象,然后由工厂生产对象交给客户,客户去具体考虑的使用对象中的方法。而策略模式则有所不同,客户自己创建对象,但是当客户需要调用对象的方法时,则交由另一个环境角色类(Context)来实现,客户本身不关心方法的具体实现过程。
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。在这种模式中,主要有三种角色:

  • 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
  • 具体策略角色:包装了相关的算法和行为。
  • 环境角色:持有一个策略类的引用,最终给客户端调用。

简单来说,策略模式中客户产生其所想要的具体策略所对应的对象,并传给环境角色,由环境角色来完成具体策略的调用然后返回给客户。

还是以计算器为例,当客户需要加法运算时,就生产一个加法运算的对象,并输入加法运算的两个操作数,这时候把这个对象丢给环境角色,环境角色就会去调用具体实现加法的算法并将结果返回给客户。因此策略模式的优点是隔离了客户和具体方法,适合类中的成员以方法为主、算法经常变动的情况。但是策略模式也有明显的缺点,那就是在客户端去判断应该使用哪一个对象并要生产它,那么现在我们考虑将策略模式与简单工厂模式相结合,看看会有什么效果。我们给工厂角色加入环境角色的功能,也就是说对象的生产仍然通过客户告诉工厂角色来完成,同时工厂角色调用所产生对象的具体方法并将结果返回给客户。这么做的好处是客户无需关心对象的生产和具体方法的实现,在客户端只需知道工厂角色一个类就可以,综合了两种模式的优点。

综合回顾一下三种模式,试想有一个机器,它承担着工厂角色、环境角色或是两者结合的职责。在简单工厂模式中,客户在机器上输入对象的名称,机器就把这个对象生产出来,客户拿到这个对象就能使用它的方法;在策略模式中,客户把自己手里的对象放到这个机器里,机器去调用对象的方法,把结果显示给客户;而在两种模式相结合的情况下,客户在机器上输入对象的名称,机器把这个对象生产出来并调用它的方法,最后把结果显示给客户。

下面给出策略模式代码,由于运算基类、具体运算类和简单工厂模式一样就不再重复了,只给出环境角色类和客户端部分。

class Context//环境角色类{private:	COperation* op;//指向客户产生的对象public:	Context(COperation* temp, int firstNum, int secondNum)	{		op=temp;		op->SetFirst(firstNum);		op->SetSecond(secondNum);	}	double GetResult()//调用对象的具体方法	{		return op->GetResult();	}	~Context()	{		delete op;	}};int main(){	int firstNum, secondNum;	char oper;	cout << "Please input first number:" << endl;	cin >> firstNum;	cout << "Please input operator:" << endl;	cin >> oper;	cout << "Please input second number:" << endl;	cin >> secondNum;	Context *context;	switch(oper)	{	case ‘+‘:		context=new Context(new CAdd(), firstNum, secondNum);		break;	case ‘-‘:		context=new Context(new CSub(), firstNum, secondNum);		break;	}	cout << "The result is: " << context->GetResult() << endl;	return 0;}

下面是两种模式相结合的代码:

class FactoryContext//简单工厂与策略模式混合类{private:	COperation* op;public:	FactoryContext(char cType, int firstNum, int secondNum)	{		switch (cType)//根据客户要求生产对象		{		case ‘+‘:			op=new CAdd();			op->SetFirst(firstNum);			op->SetSecond(secondNum);			break;		case ‘-‘:			op=new CSub();			op->SetFirst(firstNum);			op->SetSecond(secondNum);			break;		}	}	double GetResult()//调用所生产对象的具体方法	{		return op->GetResult();	}	~FactoryContext()	{		delete op;	}};int main()//客户端{	int firstNum, secondNum;	char oper;	cout << "Please input first number:" << endl;	cin >> firstNum;	cout << "Please input operator:" << endl;	cin >> oper;	cout << "Please input second number:" << endl;	cin >> secondNum;	FactoryContext *conFactory = new FactoryContext(oper, firstNum, secondNum);	cout << "The result is: " << conFactory->GetResult() << endl;	delete conFactory;	return 0;}

 

设计模式(二):策略模式