往期地址:
本期主题:
讲解策略模式,并有c++实例
0.设计模式分类
设计模式可按照对对象的操作方式进行分类,一般可分为三类:
- 创建型设计模式: 提供创建对象的机制,提高已有代码的灵活性,像前面所讲的简单工厂模式便属于创建型设计模式;
- 结构型设计模式: 将对象和类组成较大的结构,保证结构的灵活和高效;
- 行为设计模式: 行为模式负责对象间的高效沟通和职责委派;
1.策略模式是什么
策略模式是一种行为设计模式,适用的场景是:
当定义了一系列算法,可以将每种算法放入独立的类中,当算法发生改变时,后续维护可不改变其他代码,让算法相互替换;
2.例子
实现一个超市收费的系统,可以有多种模式收费,正常收费、打八折模式、按照积分计算返利模式…
1 用简单工厂模式有何问题?
使用上一篇文章讲到的简单工厂模式的话,我们会这么设计:
- 会创建一个收费抽象类,这是对产品的抽象;
- 会有各种各样的产品继承这个收费抽象类,各种各样的产品就是各种的收费算法;
- 还有一个收费工厂类,来生产具体的产品
1.UML图:
2.代码:
代码如下:
#define NORMAL (0)
#define REBATE (1)
//产品,收费抽象类
class Cash_charge
{
public:
virtual double accpetCash(double money) = 0;
};
//具体产品
//正常收费类,8折收费类,...
class Cash_Normal : public Cash_charge
{
double accpetCash(double money)
{
return money;
}
};
class Cash_Rebate : public Cash_charge
{
double accpetCash(double money)
{
return 0.8 * money;
}
};
//工厂,收费工厂类
class Cash_Factory
{
public:
Cash_charge* Create_Cash_Accpet(char op)
{
Cash_charge *cash_charge = NULL;
// cout << "op : " << op << endl;
printf("op is %d\r\n", op);
switch (op)
{
case NORMAL:
cout << "NORMAL" << endl;
cash_charge = new Cash_Normal();
break;
case REBATE:
cout << "REBATE" << endl;
cash_charge = new Cash_Rebate();
break;
default:
cout << "defautl" << endl;
break;
}
return cash_charge;
}
};
int main()
{
int op = 0;
float money;
float result;
cout << "请输入计费模式: 0代表normal, 1代表8折 :";
cin >> op;
cout << "请输入结账金额 :";
cin >> money;
Cash_Factory cash_factory_ins;
Cash_charge *cash_charge_ins = NULL;
cash_charge_ins = cash_factory_ins.Create_Cash_Accpet(op);
if (cash_charge_ins == NULL)
{
cout << "cash_charge_ins is NULL! \r\n";
return -1;
}
result = cash_charge_ins->accpetCash(money);
cout << "result : %d" << result << endl;
}
3.问题分析:
这样写还是存在后续的维护问题,假如商场的收费策略经常在变动,那么每次都至少需要改动两个地方:
- 需要新增收费类(描述收费策略);
- 需要改动工厂生成(简单可理解需要增加switch case)
这样导致每次收费策略变动,都需要重新部署编译工厂类
,有什么办法能避免这种情况吗?
这就引出了我们的策略模式;
2 用策略模式来实现
策略模式的实现步骤:
- 定义一系列的算法,每种算法是独立的类;
- 算法对外的接口抽象,放在策略类中去实现,策略类独立于具体策略;
- 关键点: 策略类并不执行策略,而是负责将工作派给已连接的具体策略;
2.1.UML图
2.2.代码
//产品,收费抽象类
class Cash_charge
{
public:
virtual double accpetCash(double money) = 0;
};
//具体产品
//正常收费类,8折收费类,...
class Cash_Normal : public Cash_charge
{
double accpetCash(double money)
{
return money;
}
};
class Cash_Rebate : public Cash_charge
{
double accpetCash(double money)
{
return 0.8 * money;
}
};
//创建一个策略类,后面更新就不需要再更改策略类,只需要增加新的收费类即可
class Cash_Context
{
public:
Cash_charge *cash_charge_ins;
Cash_Context(Cash_charge *Cash_charge)
{
this->cash_charge_ins = Cash_charge;
}
double get_result(double money)
{
return (this->cash_charge_ins->accpetCash(money));
}
};
int main()
{
int op = 0;
double money;
double result;
// cout << "请输入计费模式: 0代表normal, 1代表8折 :";
// cin >> op;
cout << "请输入结账金额 :";
cin >> money;
Cash_Factory cash_factory_ins;
Cash_charge *cash_charge_ins = NULL;
Cash_Context cash_context_ins = Cash_Context(new Cash_Rebate());
result = cash_context_ins.get_result(money);
cout << "result : %f" << result << endl;
}
}