在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
下面以一个收费系统为例,实现正常收费、返利收费、打折收费的功能。
首先创建策略类:
/// <summary>
/// 结算方式抽象类
/// </summary>
abstract class Strategy
{
/// <summary>
/// 结算方式抽象方法
/// </summary>
/// <returns></returns>
public abstract double AcceptCash();
}
/// <summary>
/// 正常收费
/// </summary>
class CashNormal:Strategy
{
private double money;
private int number;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="money">单价</param>
/// <param name="number">数量</param>
public CashNormal(double money,int number)
{
this.money = money;
this.number = number;
}
/// <summary>
/// 正常收费金额
/// </summary>
/// <returns></returns>
public override double AcceptCash()
{
return money * number;
}
}
/// <summary>
/// 返利收费
/// </summary>
class CashReturn:Strategy
{
private double money;
private int number;
private double moneyCondition;
private double moneyReturn;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="money">单价</param>
/// <param name="number">数量</param>
/// <param name="moneyCondition">满多少</param>
/// <param name="moneyReturn">返多少</param>
public CashReturn(double money,int number,double moneyCondition, double moneyReturn)
{
this.money = money;
this.number = number;
this.moneyCondition = moneyCondition;
this.moneyReturn = moneyReturn;
}
/// <summary>
/// 返利收费方法
/// </summary>
/// <returns></returns>
public override double AcceptCash()
{
double amount = 0;
amount = money * number;
amount -= (int)(amount / moneyCondition) * moneyReturn;
return amount;
}
}
/// <summary>
/// 折扣收费
/// </summary>
class CashRebate:Strategy
{
private double money;
private int number;
private double moneyRebate;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="money">单价</param>
/// <param name="number">数量</param>
/// <param name="moneyRebate">折扣</param>
public CashRebate(double money,int number,double moneyRebate)
{
this.money = money;
this.number = number;
this.moneyRebate = moneyRebate;
}
/// <summary>
/// 折扣收费方式
/// </summary>
/// <returns></returns>
public override double AcceptCash()
{
return money * number * moneyRebate;
}
}
然后创建context类:
class CashContext
{
/// <summary>
/// 声明Strategy对象
/// </summary>
Strategy strategy = null;
/// <summary>
/// 根据不同的收费方式实例化不同的对象
/// </summary>
/// <param name="type">收费方式</param>
/// <param name="money">单价</param>
/// <param name="number">数量</param>
public CashContext(string type,double money,int number)
{
switch (type)
{
case "正常收费":
CashNormal cashNormal = new CashNormal(money, number);
strategy = cashNormal;
break;
case "满300返100":
CashReturn cashReturn = new CashReturn(money, number, 300, 100);
strategy = cashReturn;
break;
case "打8折":
CashRebate cashRebate = new CashRebate(money, number, 0.8);
strategy = cashRebate;
break;
}
}
/// <summary>
/// 获取总金额
/// </summary>
/// <returns></returns>
public double GetResult()
{
return strategy.AcceptCash();
}
}
最后是客户端代码:
public Form1()
{
InitializeComponent();
this.cbxType.SelectedIndex = 0;
}
private void btnOK_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(this.textPrice.Text)||string.IsNullOrWhiteSpace(this.textNum.Text))
{
MessageBox.Show("单价和数量不能为空!");
return;
}
double money = Convert.ToDouble(this.textPrice.Text);
int number = Convert.ToInt32(this.textNum.Text);
string type = this.cbxType.SelectedItem.ToString();
CashContext cashContext = new CashContext(type, money, number);
double result = cashContext.GetResult();
string strMessage = string.Format("单价:{0},数量:{1},结算方式:{2},合计:{3}", money, number, type, result);
this.lbxList.Items.Add(strMessage);
}