一,理论学习:
1.什么叫策略模式?
定义了一族算法,将每个算法分别封装起来,并相互之间可以替换。策略模式可以使算法的变化独立于使用算法的客户!
对于上面书上的标准定义总是说的比较简洁和深刻,不仔细琢磨还真让人有点摸不着头脑!个人通俗的理解如下:“策略”这个词顾名思义就是解决一个问题的方法!我们都知道一般来说解决一个问题有多种方法(策略),比如下面我写的这个例子,要解决商场对顾客的收费问题,对不同的顾客我有不同的收费策略(方法)!例如对一级会员我的收费策略是消费满200送50,对二级会员的收费策略是打9折,对不是会员的消费者我的收费策略是没有优惠按正常收费。策略模式要做的就是把我刚才讲的每一种收费策略都封装起来,并且根据顾客类型的不同相互之间可以替换!例如我现在要把对一级会员的消费策略从以前的消费满200送50改成现在打9折的消费策略,而把对二级会员的消费策略从以前的打9折改成现在满200送50,把一级会员的和二级会员的消费策略对换一下,对于这样问题是比较容易解决的!这是因为顾客的类型和消费策略之间两者没有耦合性,可以实现任意组合!也就是说算法的变化可以独立于使用算法的客户!客户需要对哪种顾客使用哪种收费策略,我只需将两者组合即可,并且这个组合可以动态地进行。
2.策略模式的组成:
2.1 抽象策略角色:策略类,通常由一个接口或者抽象类实现,比如我写的例子中Charge类和Membership类都是扮演的抽象策略角色。
2.2 具体策略角色:包装了相关的算法和行为。Charge类和Membership类的子类都是具体策略角色,负责具体实现抽象策略角色。
2.3 环境角色:持有一个策略类的引用,最终给客户端调用。Concrete_Charge_Context类就是环境角色,虽然这里面使用工厂模式方法,封装了对象创建!
3.策略模式的优点:
3.1 封装性好。
3.2 实现和抽象的依赖性很小(组合对象和被组合对象之间的依赖性很小)。
3.3 可以在运行期间动态地定义实现。
4.应用场景:
4.1 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
4.2 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。(这一条我写的例子中有体现)
4.3 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。(这一条我写的例子中有体现)
二,策略模式在简单的商场收费软件中的应用:
<pre name="code" class="cpp">#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
//定义收费的类型作为基类
class Charge
{
public:
virtual double charge(double money) = 0;
};
//正常收费
class Normal_Charge :public Charge
{
public:
virtual double charge(double money)
{
return money;
}
};
//打折收费
class Discount_Charge :public Charge
{
public:
Discount_Charge(double d) :discount(d){}
virtual double charge(double money)
{
return (money*discount);
}
private:
double discount;//折扣
};
//返还现金
class Return_Charge :public Charge
{
public:
Return_Charge(double mc, double mr) :money_condition(mc), money_return(mr){}
virtual double charge(double money)
{
double result = money;
if (money > money_condition)
result = money - (int)(money / money_condition)*money_return;
return result;
}
private:
double money_condition;//返回现金的最低消费下限
double money_return;//返回现金的数目
};
//抽象类:会员
class Membership
{
public:
virtual void Get_Name() = 0;
virtual bool Search_Name() = 0;
};
//子类:一级会员
class One_level_Membership :public Membership
{
public:
virtual void Get_Name()
{//输入名字
cout << "请输入你的名字:";
cin >> name;
}
virtual bool Search_Name()
{//查询客户的姓名,若为一级会员,则返回true,否则返回false
string array[] = { "张三", "李四", "马良君", "邓洋洋" };
ivec.insert(ivec.end(), array, array + 4);
string search_value = name;
vector<string>::const_iterator iter = find(ivec.begin(), ivec.end(), search_value);
if (iter == ivec.end())
return false;
else
return true;
}
private:
string name;
vector<string> ivec;
};
//子类:二级会员
class Two_level_Membership :public Membership
{
public:
virtual void Get_Name()
{//输入名字
cout << "请输入你的名字:";
cin >> name;
}
virtual bool Search_Name()
{//查询客户的姓名,若为一级会员,则返回true,否则返回false
string array[] = { "王五", "马六", "李刚", "张刚" };
ivec.insert(ivec.end(), array, array + 4);
string search_value = name;
vector<string>::const_iterator iter = find(ivec.begin(), ivec.end(), search_value);
if (iter == ivec.end())
return false;
else
return true;
}
private:
string name;
vector<string> ivec;
};
class Concrete_Charge_Context
{
public:
Concrete_Charge_Context(int type)
{
double money;
switch (type)
{
case 1:
{
ms = new One_level_Membership;
ch = new Return_Charge(200, 50);
ms->Get_Name();
if (ms->Search_Name())
{
cout << "欢迎你!一级会员顾客!" << endl;
cout << "请输入总购物款:";
cin >> money;
cout << "一级会员满200送50!" << endl;
cout << "请付" << ch->charge(money) << "元!" << endl;
}
else
cout << "您不是一级会员!" << endl;
delete ms;
delete ch;
}break;
case 2:
{
ms = new Two_level_Membership;
ch = new Discount_Charge(0.9);
ms->Get_Name();
if (ms->Search_Name())
{
cout << "欢迎你!二级会员顾客!" << endl;
cout << "请输入总购物款:";
cin >> money;
cout << "二级会员打9折!" << endl;
cout << "请付" << ch->charge(money) << "元!" << endl;
}
else
cout << "您不是二级会员!" << endl;
delete ms;
delete ch;
}break;
case 3:
{
ch = new Normal_Charge;
cout << "请输入总购物款:";
cin >> money;
cout << "您不是会员,按正常收费!" << endl;
cout << "请付" << ch->charge(money) << "元!" << endl;
delete ch;
}break;
}
}
private:
Charge*ch;
Membership*ms;
};
int main(void)
{
cout << "请选择顾客类型:" << endl;
cout << "1.一级会员" << endl;
cout << "2.二级会员" << endl;
cout << "3.非会员普通顾客" << endl;
cout << endl;
cout << "请输入您的选择:";
int choise;
cin >> choise;
switch (choise)
{
case 1:
{
Concrete_Charge_Context*p1 = new Concrete_Charge_Context(1);
delete p1;
}break;
case 2:
{
Concrete_Charge_Context*p2 = new Concrete_Charge_Context(2);
delete p2;
}break;
case 3:
{
Concrete_Charge_Context*p3 = new Concrete_Charge_Context(3);
delete p3;
}break;
default:cout << "您输入有误!" << endl;
}
cout << endl << endl;
system("pause");
return 0;
}