Loading

设计模式之策略模式

1|策略模式定义

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用不同的算法,减少了各种算法类与使用算法类之间的耦合。

2|策略模式优缺点及使用场景

2.1 优点

策略模式的Stragey类层次为Context定义了一系列的可供重用的算法或行为。继承有助于析取这些算法中的公共功能。另外,策略模式还简化了单元测试,因为每个算法都有自己的类,可以通过自己的接口单独测试。

2.2 缺点

因为在使用Stragey时会根据不同场景实例化不同的算法,所以可能会充斥着大量判断分支。

2.3 使用场景

在不同时间使用不同的业务规则时就可以考虑使用策略模式。

3|策略模式结构及实现

3.1 结构

image-20210623233002916

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();
        }

微信截图_20210623232644

3.3 源代码

完整示例源代码:https://github.com/luchong0813/DesignModel/tree/main/StrategyPattern

posted @ 2021-06-23 23:52  傲慢与偏见luc  阅读(112)  评论(0编辑  收藏  举报