• C#设计模式之策略模式


     

     背景:

      策略模式在我们实际项目开发中,使用的比较多的一种设计模式,直接贴一个demo处理供大家参考,如有不对的地方,多多指点交流

    定义:

      策略模式是针对一组算法,将每个算法封装到具有公共接口的独立的类中,
      从而使它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

    角色: 

      环境角色(Context):持有一个Strategy类的引用
      抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类来实现。
      此角色给出所有具体策略类所需实现的接口。
      具体策略角色(ConcreteStrategy):包装了相关算法或行为。

    使用场景:

     系统中如果有几个产品分支,而每一次处理逻辑只会执行其中一个条分支,那么这时可以考虑使用策略模式,易于后期的可扩展,避免大堆的if else

      比如:

      结算:复杂一点系统结算的时候,会根据不同的角色,其结算方式有所不同

      支付:其实系统支付的时候,会有不同的支付渠道,用户在实际支付的时候只会用一种支付渠道

     

    主要优点:

      策略类之间可以自由切换。由于策略类都实现同一个接口,所以使它们之间可以自由切换。
      易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码。

    主要缺点:

      使用方需要了解所有策略实现,并自行决定调用那一策略。

           为了使用方灵活,可以采用依赖注入方式来处理,微软提供了一个依赖注入技术:unity,可以参考使用

    代码示例:

      

    using Microsoft.Practices.Unity.Configuration;
    using System;
    using System.Configuration;
    using Unity;
    
    /// <summary>
    /// 定义:策略模式是针对一组算法,将每个算法封装到具有公共接口的独立的类中,
    ///       从而使它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
    /// 结构:策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象负责。
    ///       策略模式通常把一系列的算法包装到一系列的策略类里面。用一句话慨括策略模式就是
    ///       ——“将每个算法封装到不同的策略类中,使得它们可以互换”
    /// 角色:
    ///      环境角色(Context):持有一个Strategy类的引用
    ///      抽象策略角色(Strategy):这是一个抽象角色,通常由一个接口或抽象类来实现。
    ///                                 此角色给出所有具体策略类所需实现的接口。
    ///      具体策略角色(ConcreteStrategy):包装了相关算法或行为。
    ///      
    /// 主要优点:
    
    //···策略类之间可以自由切换。由于策略类都实现同一个接口,所以使它们之间可以自由切换。
    //···易于扩展。增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码。
    //···避免使用多重条件选择语句,充分体现面向对象设计思想。
    //  主要缺点:
    
    //··客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
    //```这点可以考虑使用IOC容器和依赖注入的方式来解决,关于IOC容器和依赖注入(Dependency Inject)
    /// </summary>
    namespace StragetyPattern
    {
        // 步骤 1 抽象策略角色
        //创建一个接口。
        public interface Strategy
        {
            int doOperation(int num1, int num2);
        }
    
        //    步骤 2 具体策略角色
        //创建实现接口的实体类。
        public class OperationAdd : Strategy
        {
            public int doOperation(int num1, int num2)
            {
                return num1 + num2;
            }
        }
    
        public class OperationSubstract : Strategy
        {
            public int doOperation(int num1, int num2)
            {
                return num1 - num2;
            }
        }
    
        public class OperationMultiply : Strategy
        {
            public int doOperation(int num1, int num2)
            {
                return num1 * num2;
            }
        }
    
        //    步骤 3 环境角色
        //创建 Context 类。调度作用
        public class Context
        {
            private Strategy strategy;
    
            public Context(Strategy strategy)
            {
                this.strategy = strategy;
            }
    
            public int executeStrategy(int num1, int num2)
            {
                return strategy.doOperation(num1, num2);
            }
        }
    
    
        //    步骤 4
        //使用 Context 来查看当它改变策略 Strategy 时的行为变化。
        public class Program
        {
            private static IUnityContainer container = null;
    
            static void Main(string[] args)
            {
                RegisterContainer();
    
                Context context = new Context(container.Resolve<Strategy>("ADD"));
                Console.WriteLine("10 + 5 = " + context.executeStrategy(10, 5));
    
                context = new Context(container.Resolve<Strategy>("SUB"));
                Console.WriteLine("10 - 5 = " + context.executeStrategy(10, 5));
    
                context = new Context(container.Resolve<Strategy>("MUL"));
                Console.WriteLine("10 * 5 = " + context.executeStrategy(10, 5));
    
                Console.ReadKey();
            }
    
            private static void RegisterContainer()
            {
                container = new UnityContainer();
                UnityConfigurationSection config = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName);
                config.Configure(container, "Programmer");
            }
        }
    }
  • 相关阅读:
    JS-BOM操作-Location、history、常用弹窗、屏幕属性
    JS的基础DOM操作-选取父子级元素、动态生成元素、修改元素、Classlist
    setup
    循环请求接口,统一处理
    多个url文件下载
    扁平数据结构转Tree
    es6 解构赋值
    watch与computed与props
    v-model与.sync组件通信
    v-on="$listeners"和v-bind="$attrs"
  • 原文地址:https://www.cnblogs.com/xiaoXuZhi/p/designPattern_StragetyPattern.html
Copyright © 2020-2023  润新知