策略模式的定义:ios
策略模式是指定义一系列的算法,把它们一个个封装起来,而且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。算法
优势: 一、算法能够自由切换。 二、避免使用多重条件判断。 三、扩展性良好。编程
缺点: 一、策略类会增多。 二、全部策略类都须要对外暴露。设计模式
类图以下:函数
Strategy: 抽象策略类,定义抽象的函数算法让继承的子类实现。spa
ConcreteStrategy:封装了继续相关的算法和行为,即函数的具体功能的实现。设计
Context:持有一个策略类的引用,最终给客户端调用。指针
我认为策略模式的重点在于context类的定义,这也是策略模式与模板模式最大的不一样,即经过对策略基类Strategy的组合出的类context,根据子类的不一样,灵活地经过类context中的多态指针调用来实现一系列子类算法,也叫根据不一样策略执行不一样的行为。策略由外部环境决定。code
总结起来就是Context 指向 Strategy (由指针实现);Context 经过 Strategy 接口,调用一系列算法;ConcreteStrategy 实现了一系列具体的算法。blog
下面举一个例子来讲明策略模式的好处:
假如一个跨国公司A在多个国家有分公司,且在不一样国家的经营模式根据国家国情会有所不一样,并且分公司负责人也不一样,要求编写程序实现这一状况的描述。首先容易想到的是定义一个基类,而后针对不一样的分公司用switch语句进行选择来编写。代码以下:
1
#include <iostream>
using namespace std;
class Company
{
private:
string name;
int type;
public:
Company(string n,int t)
{
name=n;
type=t;
}
void printcompany()
{
switch(type)
{
case 1:
cout<<"负责人"<<name<<endl;
China();
break;
case 2:
cout<<"负责人"<<name<<endl;
America();
break;
case 3:
cout<<"负责人"<<name<<endl;
France();
break;
}
}
void China()
{
cout<<"中国分公司:经营模式1的具体实现..."<<endl;
}
void America()
{
cout<<"美国分公司:经营模式2的具体实现..."<<endl;
}
void France()
{
cout<<"法国分公司:经营模式3的实现..."<<endl;
}
};
int main()
{
Company a1("张三",1);
Company a2("李四",2);
Company a3("王五",3);
a1.printcompany();
cout<<"================================================="<<endl;
a2.printcompany();
cout<<"================================================="<<endl;
a3.printcompany();
}
然而这个程序只是最简单的作法,其扩展性并很差,例如要在印度一个新分公司,须要在类添加相关公司经营模式函数,也要在switch添加相关公司内容,若是某个分公司的经营模式要改变,也要经过去类中寻找相应的函数去修改,但若是分公司多了,类就会变得很臃肿且不方便查找修改。若是咱们采用策略模式,把函数定义写在抽象基类中,把每一个分公司写成一个继承子类,由不一样的算法实现不一样经营模式,而后再写一个封装的context类来实现客户端调用,这样就能够一目了然了,创建分公司和修改信息就只须要对子类进行操做,基类并不须要任何修改,并且经过contex类提供的接口能够很方便的选择展现不一样公司的状况,代码以下:
#include <iostream> using namespace std; class Company { public: string name; virtual void Management()=0; }; class Company1:public Company { public: Company1(string n) {
name=n; } void printcompany() { cout<<"负责人"<<name<<endl; } virtual void Management() { cout<<"中国分公司:经营模式1的具体实现..."<<endl; } }; class Company2:public Company { public: Company2(string n) { name=n; } void printcompany() { cout<<"负责人"<<name<<endl; } virtual void Management() { cout<<"美国分公司:经营模式2的具体实现..."<<endl; } }; class Company3:public Company { public: Company3(string n) { name=n; } void printcompany() { cout<<"负责人"<<name<<endl; } virtual void Management() { cout<<"法国分公司:经营模式3的实现..."<<endl; } }; class Context { public: Company *com; Context(Company *c) { com=c; } void printcompany() { com->Management(); } }; int main() { Company *china=new Company1("张三"); Company *america=new Company2("张三"); Company *france=new Company3("张三"); Context a1(china); Context a2(america); Context a3(france); a1.printcompany(); cout<<"================================================="<<endl; a2.printcompany(); cout<<"================================================="<<endl; a3.printcompany(); }
从设计模式的角度来讲,这种模式隔离变化,编程到接口,有新公司加入,只要写一个子类就能够,不须要改变其余类的代码,因此其余的类都是稳定的,这就体现了咱们策略模式的设计原则和目的。