策略模式
一切来自好奇心
核心
面向对象要完成一件事,先想这件事谁去做,后是怎么做,那么做同一件事情完成的方案方法不同,就是用不同策略完成。策略模式是定义一系列算法的方法,从概念上看所有的算法都完成相同的工作,只是实现不同,他可以用相同方式调用所有算法,减少了算法类之间的耦合。
好处
能把完成同一件事情的很多算法中的公共功能析取出来,在业务中我们听见在不同情况下用不同规则完成这件事时就要考虑这种方法。而且最好结合简单工厂模式,能减轻客户端的判断压力,转给策略模式Context对象。
例子
首先是一个策略模式。情景是:商场的付款方式变化引起的结款不同。(正常收费,打折收费,返利等等)
创建抽象策略类和具体实现策略类
//抽象收费类
abstract class CashSuper
{
public abstract double acceptCash(double money);
}
//正常收费子类
class CashNomal : CashSuper
{
public override double acceptCash(double money)
{
return money;
}
}
//打折收费子类
class CashRebate : CashSuper
{
private double moneyRebate = 1d;
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double acceptCash(double money)
{
return money * moneyRebate;
}
}
//返利收费子类
class CashReturn : CashSuper
{
private double moneyConduction = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(string moneyConduction, string moneyReturn)
{
this.moneyConduction = double.Parse(moneyConduction);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double acceptCash(double money)
{
double result = money;
if (money >= moneyConduction)
result = money - Math.Floor(money / moneyConduction) * moneyReturn;
return result;
}
}
方案一 (未结合工厂的策略模式)
class CashContext
{
//策略核心类CashContext类
private CashSuper cs;
public CashContext(CashSuper csuper)
{
this.cs = csuper;
}
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
//客户端
private void button1_Click(object sender, EventArgs e)
{
CashContext cc = null;
switch (comboBox1.SelectedItem.ToString())
{
case "正常收费":
cc = new CashContext(new CashNomal());
break;
case "满300返100":
cc = new CashContext(new CashReturn("300","100"));
break;
case "打8折":
cc = new CashContext(new CashRebate("0.8"));
break;
}
double totalPrices = 0d;
totalPrices = cc.GetResult(Convert.ToDouble(textBox1.Text)*Convert.ToDouble(textBox2.Text));
total = totalPrices + total;
listBox1.Items.Add("单价:" + textBox1.Text + "数量:" + textBox2.Text + "计算方式:" + comboBox1.SelectedItem + "合计:" + totalPrices.ToString
label4.Text = total.ToString();
}
方案二 (结合工厂的策略模式)
class CashContext
{
//策略核心类CashContext类
CashSuper cs = null;
public CashContext(string type)
{
switch (type)
{
case "正常收费":
CashNomal cs0 = new CashNomal();
cs = cs0;
break;
case "满300返100":
CashReturn cs1 = new CashReturn("300","100");
cs = cs1;
break;
case "打8折":
CashRebate cs2 = new CashRebate("0.8");
cs = cs2;
break;
}
}
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
//客户端
private void button1_Click(object sender, EventArgs e)
{
CashContext csuper = new CashContext(comboBox1.SelectedItem.ToString());
double totalPrices = 0d;
totalPrices = csuper.GetResult(Convert.ToDouble(textBox1.Text)*Convert.ToDouble(textBox2.Text));
total = totalPrices + total;
listBox1.Items.Add("单价:" + textBox1.Text + "数量:" + textBox2.Text + "计算方式:" + comboBox1.SelectedItem + "合计:" + totalPrices.ToString());
label4.Text = total.ToString();
}
例子来源:Linux公社《大话设计模式》
实例代码在我的代码托管上