策略模式:定义了算法家族,分别封装起来,让他们之间的可以互相替换,让算法的变化,不会影响到使用算法的用户。
在商场收银系统中,促销中无论打折还是返利,都是一些算法,这些算法都是可以互换的,作为变化点封装起来,策略模式的设计原则即把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为,从而实现算法和对象的分开。
策略模式的结构图:
商场收银系统代码:
<span style="font-size:14px;">
现金收费抽象类
abstract class CashSuper
{
public abstract double acceptCash(double money);
}
正常收费子类
class CashNormal : CashSuper
{
public override double acceptCash(double money)
{
return money;
}
}
打折收费子类
class CashRebate : CashSuper
{
private double moneyRobate = 1d
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double acceptCash(double money)
{
return money*moneyRebate;
}
}
返利收费子类
class CashReturn : CashSuper
{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(string moneyCondition,string moneyReturn)
{
this.moneyCondition = double.Prase(moneyCondition);
this.moneyReturn = double.Prase(moneyReturn);
}
public override double acceptCash(double money)
{
double result = money;
if (money >= moneyConditon)
result = money - Math.Floor(money /moneyCondition)*moneyReturn; /Math.Floor用于取整数
return result;
}
}
</span>
<span style="font-size:14px;">CashContext类
class CashContext
{
CashSuper cs = null;
public CashContext(string type)
{
switch(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 CashRebate("0.8");
cs = cr2;
break;
}
}
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
</span>
<span style="font-size:14px;">
客户端代码
double total = 0.0d
private void btnOK_Click(object sender,EventArgs e)
{
CashContext csuper = new CashContext(cbxType.SelectedItem.Tostring());
double totalprices = 0d;
totalPrices=csuper.GetResult(Convert.ToDouble(txtPrice.Text)*Convert.ToDouble(txtNum.Text));
total= total +totalPrices;
lbxList.Ttems.Add("单价:"+ txtPrice.Text+"数量:"+txtNum.Text+""+cbxType.SelectedItem + "合计:"+ totalPrices.ToString());
lblResult.Text = total.ToString();
}</span>
在客户端中通过下来菜单cbxType选择算法,在CashContext中判断选择生成与其向对应的对象,调用其算法在客户端显示出结算结果。
策略模式的好处:
定义了一系列算法,从概念上来说,所有的这些算法都是做相同的事情,只是实现不同,他可以以相同的方式调用所有的方法,减少了各种算法类与使用算法类之间的耦合。单独定义算法类,也方便了单元测试,因为可以通过自己的算法进行单独测试。
实践中,不仅可以封装算法,也可以用来封装几乎任何类型的规则,只要在分析过程中需要在不同时间应用不同的业务规则,就可以考虑是要策略模式来处理各种变化。