设计模式之策略模式
1|策略模式定义
策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用不同的算法,减少了各种算法类与使用算法类之间的耦合。
2|策略模式优缺点及使用场景
2.1 优点
策略模式的Stragey类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取这些算法中的公共功能。另外,策略模式还简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。
2.2 缺点
因为在使用Stragey时会根据不同场景实例化不同的算法,所以可能会充斥着大量判断分支。
2.3 使用场景
在不同时间使用不同的业务规则时就可以考虑使用策略模式。
3|策略模式结构及实现
3.1 结构
3.2 代码实现
抽象出一个公共类,比如我这里抽取出了一个计算的抽象类
public abstract class CashSuper
{
public abstract double acceptCash(double money);
}
在子类(不同的业务规则子类)中继承抽象父类并实现抽象方法
/// <summary>
/// 返利策略
/// </summary>
public class CashReturn : CashSuper
{
private double _conditionMoney;
private double _returnMoney;
public CashReturn(double conditionMoney, double returnMoney)
{
_conditionMoney = Convert.ToDouble(conditionMoney);
_returnMoney = Convert.ToDouble(returnMoney);
}
public override double acceptCash(double money)
{
var result = money;
if (money >= _conditionMoney)
{
result = money - Math.Floor(money / _conditionMoney) * _returnMoney;
}
return result;
}
}
接着,再创建一个上下文类来维护对Stragey对象的引用
public class CashContext
{
CashSuper cashSuper = null;
public CashContext(string type)
{
switch (type)
{
case "正常收费":
cashSuper = new CashNormal();
break;
case "打8折":
cashSuper = new CashRebate(0.8);
break;
case "满300返100":
cashSuper = new CashReturn(300, 100);
break;
default:
cashSuper = new CashNormal();
break;
}
}
/// <summary>
/// 获取计算价格结果
/// </summary>
/// <param name="money"></param>
/// <returns></returns>
public double GetResult(double money)
{
return cashSuper.acceptCash(money);
}
最后,在客户端通过调用上下文类来调用不同的算法。客户端只要认识这个上下文类就好了,无需关系不同业务规则的具体实现。
private void GoodsAddBtn_Click(object sender, RoutedEventArgs e)
{
CashContext context = new CashContext(CbCaclc.SelectedItem.ToString());
var totalPrice = context.GetResult(Convert.ToDouble(TextGoodsPrice.Text) * Convert.ToDouble(TextGoodsNum.Text));
total += totalPrice;
lBGoodsTodo.Items.Add($"名称:{TextGoodsName.Text}--数量:{TextGoodsNum.Text}--合计:{totalPrice}");
TextTotal.Text = total.ToString();
}
3.3 源代码
完整示例源代码:https://github.com/luchong0813/DesignModel/tree/main/StrategyPattern