zoukankan      html  css  js  c++  java
  • 通俗易懂设计模式解析——策略模式

    前言

      今天我们来看策略模式【Stragety Pattern【行为型】】,这个模式还是比较好理解的。策略怎么理解呢?一般是指:1. 可以实现目标的方案集合;2. 根据形势发展而制定的行动方针和斗争方法;3. 有斗争艺术,能注意方式方法。总的来说呢就是针对一个目的的不同的方法集合。这里要讲的策略模式怎么理解呢?简单的说就是对于一个类的行为或者其算法可以在运行时更改替换。

    策略模式介绍

    一、来由

      在软件系统中,一些对象使用的算法或者行为可能会经常变化,如果把这些变化的算法写到对象中的话,会使对象变得较为复杂、不易理解。那么我们如何在运行时动态的修改对象的不同的算法呢?这就使用到了策略模式。

    二、意图

      定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

    三、案例图

     

    四、策略模式代码示例

      看上面的案例图好像和上一篇状态模式的案例图有点相似。都是包含的三个部分。具体区别我们看后面的详细介绍。

    环境角色:包含持有一个Strategy抽象策略的引用。

    抽象策略:定义一个公共方法,由其具体策略去实现不同算法。

    具体策略:实现抽象策略接口方法。

      这里我们看这么一个案例,在一个超市买东西。最后结算的时候都会问是否有会员,结算机制就有以下几种。普通用户全额计算。普通会员打95折。黄金会员打9折。钻石会员打8折。我们看下如何实现这一功能:

    namespace Stragety_Pattern
    {
        class StragetyPattern
        {
        }
        #region   抽象策略==================
        /// <summary>
        /// 抽象策略接口
        /// </summary>
        public interface IStragetyPattern 
        {
            /// <summary>
            /// 结算接口
            /// </summary>
            void Settlement(decimal  Money);
        }
        #endregion
    
        #region   具体策略=======================
        /// <summary>
        /// 无会员计算方式
        /// </summary>
        public class OrdinaryStragety : IStragetyPattern
        {
            public void Settlement(decimal  Money)
            {
                Console.WriteLine($"不是会员,不进行折扣结算。应付款{Money}");
            }
        }
    
        /// <summary>
        ///  普通会员计算方式
        /// </summary>
        public class MemberStragety : IStragetyPattern
        {
            public void Settlement(decimal  Money)
            {
                Console.WriteLine($"普通会员,打95折结算。应付款{Money*0.9M}");
            }
        }
    
        /// <summary>
        /// 黄金会员计算方式
        /// </summary>
        public class GoldMemberStragety : IStragetyPattern
        {
            public void Settlement(decimal  Money)
            {
                Console.WriteLine($"黄金会员,打9折结算。应付款{Money*0.95M}");
            }
        }
    
        /// <summary>
        /// 钻石会员计算方式
        /// </summary>
        public class DiamondGoldMemberStragety : IStragetyPattern
        {
            public void Settlement(decimal  Money)
            {
                Console.WriteLine($"钻石会员,打8折结算。应付款{Money*0.8M}");
            }
        }
        #endregion
    
        #region   环境角色
        public class ContextStragety 
        {
            private IStragetyPattern _stragety;
            public ContextStragety(IStragetyPattern stragety) 
            {
                _stragety = stragety;
            }
    
            /// <summary>
            /// 调用结算方法
            /// </summary>
            /// <param name="Money"></param>
            public void GetSettlement(decimal  Money) 
            {
                _stragety.Settlement( Money);
            } 
        }
        #endregion
    }
    namespace Stragety_Pattern
    {
        class Program
        {
            static void Main(string[] args)
            {
                decimal Account = 190.99M;
                ///会员计算
                ContextStragety stragety = new ContextStragety(new MemberStragety());
                stragety.GetSettlement(Account);
    
                ///普通结算 
                 stragety = new ContextStragety(new OrdinaryStragety());
                stragety.GetSettlement(Account);
            }
        }
    }

      这里我们针对最后结算的金额进行计算的时候是可以相互替换的。因为在具体策略中,都把算法的变化封装了起来。

     使用场景及优缺点

    一、使用场景

    1、如果在系统中有一些类,他们之间的区别就在于其行为的话。可以使用策略模式让一个对象在许多的行为中动态的选择一种行为。

    2、一个系统中需要在多种算法中选择一种。

    3、如果一个对象有许多的行为的话,可以简化其多重条件选择语句。避免难于维护的问题。

    二、优点

    1、策略类之间可以自由切换,因为策略类中都是实现的抽象策略的一个方法。所以可以自由切换。

    2、易于扩展,在我们新增策略的时候基本上不需要修改之前的代码。

    3、对多重条件选择语句进行优化简化

    三、缺点

    1、随着策略增多,策略类会随之增加。

    2、客户端必须知道所有的策略类,并且自行决定使用哪一种策略。

    总结

      到这里策略模式就介绍完了。策略模式主要是针对的有一系列算法。并把他们都封装起来。他们之间可以自由切换。使这些算法的变化独立于客户端的变化。也就是把多种行为之间的变化分别进行封装起来。然后在我们调用的时候可以自由的进行切换调用。

      这里我们在开篇有提到策略模式的案例图和状态模式的有点相似。这里我们重点分析一些策略模式和状态模式之间的区别吧:

    1、环境角色中的任务有所不同,策略模式的环境角色中具有一种委托作用,负责根据传进来的策略调用其算法。但是状态模式中的环境角色不仅负责这行为方法的调用,还负责有记录状态变化、与具体的状态类协作。完成状态切换之后行为的切换。

    2、策略模式主要解决的问题是将内部的算法的改变对外部的影响降低。保证算法的自由切换。状态模式主要解决的是状态的改变引起行为的变化、一个对象状态改变,从外界看来就好像是行为改变。

    3、策略模式是一个算法的封装。这里封装的一个算法可以是有意义的对象,也可以是没有意义的逻辑片段。例如这里封装加密算法。各种加密算法,可以自由切换。算法必须是平行的。状态模式是要求一些列的状态变化随着有着行为的变化。要求拥有状态和行为。


    即使受伤了,也要抬起头微笑着说,今天天气真好。

       C#设计模式系列目录

       欢迎大家扫描下方二维码,和我一起踏上设计模式的闯关之路吧!

      

  • 相关阅读:
    微软外服 AlI In One
    js 循环多次和循环一次的时间的性能对比 All In One
    vue inject All In One
    Excel 表格数据倒置 All In One
    SVG tickets All In One
    OH MY ZSH All In One
    js array for loop performance compare All In One
    mac terminal show You have new mail All In one
    新闻视频 26 制作母版页
    转自牛腩 母版页和相对路径
  • 原文地址:https://www.cnblogs.com/hulizhong/p/11678188.html
Copyright © 2011-2022 走看看