提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
实例
场景:
商场收银软件,营业员根据客户所购买商品的单价和数量,向客户收费。
一、知识点
策略模式: 它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
简单工厂模式是用工厂来生成算法对象,即封装算法,而算法本身只是一种策略,最重要的是这些算法是随时都可能互相替换的,这就是变化点,而封装变化点是面向对象的一种很重要的思维方式.
策略模式是对简单工厂模式的改进,目的是降低与客户端的耦合度。
简单工厂的部分代码:
class OperationFactory {
public:
void createOperate(string operate);
}
OperationFactory:: void createOperate(string operate) {
Operation* p;
switch (operate) {
case "+":
p = new OperationAdd();
break;
case "-":
p = new OperationSub();
break;
case "*":
p = new OperationMul();
break;
case "/":
p = new OperationDiv();
break;
}
return p;
}
//客户端代码
int main() {
Operation* per = OperationFactory.createOperate("+");
p._numberA = 1;
p._numberB = 2;
double result = p.GetResult();
}
在客户端代码中,使用OperationFactory.createOperate函数进行不同业务的逻辑判断创建相应的算法对象,并调用算法对象的方法进行运算,对于客户端来说,接口有两个。
如果,重新封装一个class context,将OperationFactory.createOperate的返回作为class的一个成员变量Operation,定义一个成员函数GetResult根据调用Operation.GetResult()供客户端调用,这样一来,只需调用context(operate).GetResult()即可。
context 兼并了OperationFactory,移除了繁杂的逻辑判断工作,同样将其结果吸收为成员变量来构建对外接口。
策略模式就是用来封装算法的,当在不同时间应用不同的业务规则时,且不同的行为堆砌在一个类时,就很难避免使用条件语句来选择合适的行为。将这些行为封装在一个个独立的strategy中,在使用这些行为的类中消除条件语句。
二、代码实现
class CashContext
{
CashSuper cs = null;
// 封装判断逻辑
public CashContext(string type)
{
case "正常收费":
CashNormal cs0 = new CashNormal(); // 省略具体的算法代码
cs = cs0;
break;
case "满300返100":
CashReturn cr1 = new CashReturn("300","100"); // 省略具体的算法代码
cs = cr1;
break;
case "打八折":
CashRebate cr2 = new CaseRebate("0.8"); // 省略具体的算法代码
cs = cr2;
break;
}
}
public double GetResult(double money)
{
return cs.acceptCash(money);//利用逻辑判断的结果,并调用其方法
}
//客户端代码
double total = 0.0d;
private void btnOk_Click(object sender, EvenArgs e)
{
CashContext csuper = new CashContext(cbxType.SelectedItem.ToString()); //将下拉框的选项传入context
double totalPrices = 0d;
totalPrinces = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text)); // 调用context的统一输出函数
total = total + totalPrices;
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + " " + cbxType.SelectedItem + "合计: " + totalPrices.ToString());
lblResult.Text = total.ToString();
}
相当于将factory的工作封装到context中,并将条件判断的结果作为context的成员变量,减少了客户端的调用接口数。