设计模式之策略模式(C#实现)

本文通过示例展示了如何使用策略模式改进支付请求处理的代码,从最初的if-else结构转变为更灵活的策略模式。在标准策略模式中,通过接口和具体策略类实现了业务逻辑的解耦。进一步地,通过改良版策略模式1.0,利用字典消除了if-else,而在改良版2.0中,使用反射动态加载新的支付策略,避免了手动更新字典。这些改进提高了代码的可维护性和扩展性。
摘要由CSDN通过智能技术生成

示例

想象一种场景,有一个方法用于支付请求,调用者需要传入很多种不同的支付类型,然后该方法使用对应的支付产品进行支付操作,先看下糟糕的实现

糟糕的代码实现

    //差的代码设计,调用端和实现端紧耦合,因为pay type还可能不断增加,那么每次都需要修改switch语言
        public void Pay_BadPractice(PayType payType)
        {
            switch (payType)
            {
                case PayType.Ali:
                    {
                        Console.WriteLine("使用了支付宝进行支付");
                    }; break;
                case PayType.WeChat:
                    {
                        Console.WriteLine("使用了微信进行支付");
                    }; break;
                case PayType.BankCard:
                    {
                        Console.WriteLine("使用了银联进行支付");
                    }; break;
            }
        }

标准的策略模式

   public void Pay_GoodPractice(PayType payType)
        {
            //标准策略模式
            //即使用了策略模式,你该写的业务逻辑照常写,到逻辑分派的时候,还是变相的if else。而它的优化点是抽象了出了接口,将业务逻辑封装成一个一个的实现类,任意地替换。在复杂场景(业务逻辑较多)时比直接 if else 来的好维护些。
            switch (payType)
            {
                case PayType.Ali:
                    {
                        IPay pay = new AliPay();
                        Context ct = new Context(pay);
                        ct.doAction();
                    }; break;
                case PayType.WeChat:
                    {
                        IPay pay = new WeChatPay();
                        Context ct = new Context(pay);
                        ct.doAction();
                    }; break;
                case PayType.BankCard:
                    {
                        IPay pay = new BankCardPay();
                        Context ct = new Context(pay);
                        ct.doAction();
                    }; break;
            }
        }


  public enum PayType
    {
        Ali,
        WeChat,
        BankCard
    }


    //策略模式有三个组成角色:
    //抽象策略(Strategy)类
    //具体策略(Concrete Strategy)类
    //环境(Context)类

    //抽象策略角色
    public interface IPay
    {
        static PayType payType { get; }
        void Pay();
    }

    //具体实现策略角色
    public class AliPay : IPay
    {
        public static PayType payType
        {
            get
            {
                return PayType.Ali;
            }
        }
        public void Pay()
        {
            Console.WriteLine("使用了支付宝进行支付");
        }
    }

    public class WeChatPay : IPay
    {
        public static PayType payType
        {
            get
            {
                return PayType.WeChat;
            }
        }
        public void Pay()
        {
            Console.WriteLine("使用了微信进行支付");
        }
    }

    public class BankCardPay : IPay
    {
        public static PayType payType
        {
            get
            {
                return PayType.BankCard;
            }
        }
        public void Pay()
        {
            Console.WriteLine("使用了银联进行支付");
        }
    }

    //Context统一管理具体实现策略的调用
    public class Context
    {
        IPay pay;
        public Context(IPay pay)
        {
            this.pay = pay;
        }

        //暴露给调用端的接口
        public void doAction()
        {
            this.pay.Pay();
        }

    }

改良版策略模式1.0(使用字典消除if else)


    //改良策略模式1,可在Context里的使用字典
    public class ContextWithDic
    {
        static Dictionary<PayType, IPay> dicPay = new Dictionary<PayType, IPay>();
        static ContextWithDic()
        {
            dicPay.Add(PayType.Ali, new AliPay());
            dicPay.Add(PayType.WeChat, new WeChatPay());
            dicPay.Add(PayType.BankCard, new BankCardPay());
        }

        //暴露给调用端的接口
        public void doAction(PayType payType)
        {
            dicPay[payType].Pay();
        }
    }

 

        public void Pay_GoodPractice(PayType payType)
        {
            //改良策略模式1,可在Context里的使用字典完全消除条件判断,缺点是每次增加新的pay策略时,需要在Context里同步增加到字典里
            new ContextWithDic().doAction(payType);
        }

改良版策略模式2.0(使用反射消除if else)

 

    public class ContextWithReflection
    {
        static Dictionary<PayType, IPay> dicPay = new Dictionary<PayType, IPay>();
        static ContextWithReflection()
        {
            var ass = Assembly.Load("DesignPatterns");
            Type[] types = ass.GetTypes();
            foreach (var item in types)
            {
                if (typeof(IPay).IsAssignableFrom(item) && item != typeof(IPay))//判断该类型是否实现了IPay接口且不是IPay本身
                {
                    var instance = Activator.CreateInstance(item);
                    var payTypeProperty = item.GetProperty("payType", BindingFlags.Public | BindingFlags.Static);//获取静态属性payType的值
                    dicPay.Add((PayType)payTypeProperty.GetValue(instance, null), (IPay)instance);
                }
            }
        }

        //暴露给调用端的接口
        public void doAction(PayType payType)
        {
            dicPay[payType].Pay();
        }
    }
        public void Pay_GoodPractice(PayType payType)
        {
            //改良策略模式2,利用反射自动将新的pay策略增加到字段里,无需修改Context类
            new ContextWithReflection().doAction(payType);
        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值