zoukankan      html  css  js  c++  java
  • 设计模式-策略模式(Strategy)

    简介:

    定义了算法家族,分别封装起来,可以让他们之间相互替换。此模式可以让算法的变化,不会影响到使用算法的客户。【行为型模式】


    结构图:


    优点:

    1. 策略模式是一种定义一系列算法的方法,从概念上来看,这些算法都是完成相同的工作,只是实现不同。它可以以相同的方式调用所有的算法,减少了各种算法类与调用算法类之间的耦合性 ;
    2. 策略模式简化了单元测试,因为每一种算法都有自己的类,可以通过调用自己的接口单独测试;
    3. 策略模式的Strategy类层次为Context定义了一系列可供重用的算法或行为。继承有助于析取出这些算法中的公共功能。

    缺点:

    1. 所有策略类都需要对外暴露;
    2. 策略类一多,就很难维护。

    应用场景:

    需要在不同时间应用不同的业务规则时,就可以使用策略模式处理这种变化的可能性。


    注意事项:

    1. 在基本策略模式中,选择所用具体实现的职责是在客户端实现,可以专有Context类型(可见示例2);
    2. 所用策略都要实现同一接口。

    示例:

    1.结构类图的实现:

    Strategy类,定义所有支持的算法的公共接口;

    ConcreteStrategy类,封装了具体的算法或行为,继承于Strategy

        /// <summary>
        /// 策略类
        /// </summary>
        public abstract class Strategy
        {
            /// <summary>
            /// 算法接口
            /// </summary>
            public abstract void AlgorithmInterface();
        }
    
        public class ConcreteStrategyA : Strategy
        {
            public override void AlgorithmInterface()
            {
                Console.WriteLine("我是策略算法A");
            }
        }
    
        public class ConcreteStrategyB : Strategy
        {
            public override void AlgorithmInterface()
            {
                Console.WriteLine("我是策略算法B");
            }
        }
    
        public class ConcreteStrategyC : Strategy
        {
            public override void AlgorithmInterface()
            {
                Console.WriteLine("我是策略算法C");
            }
        }

    Context类,用一个ConcreteStrategy来配置,维护一个Strategy对象的引用

        /// <summary>
        /// 上下文
        /// </summary>
        public class Context
        {
            private Strategy strategy;
    
            public Context(Strategy strategy)
            {
                this.strategy = strategy;
            }
            /// <summary>
            /// 上下文接口
            /// </summary>
            public void ContextInterface()
            {
                strategy.AlgorithmInterface();
            }
        }

    客户端

     Context context = new Context(new ConcreteStrategyA());
     context.ContextInterface();
     context = new Context(new ConcreteStrategyB());
     context.ContextInterface();
     context = new Context(new ConcreteStrategyC());
     context.ContextInterface();

    结果

    2.策略模式之撩妹2

    话说上次撩妹(代理模式)失败后,痛定思痛,寻求新的方法。得到一个智囊【Context】,告诉我如何在不同阶段使用不同的撩妹技巧【Strategy】。

    撩妹策略

        /// <summary>
        /// 撩妹策略接口
        /// </summary>
        public interface IChaseGirlStrategy
        {
            void ChaseGirl();
        }
        /// <summary>
        /// 相见时的策略
        /// </summary>
        public class XiangjianStrategy : IChaseGirlStrategy
        {
            public void ChaseGirl()
            {
                Console.WriteLine("1.了解女孩儿的爱好");
                Console.WriteLine("2.多和女孩聊天");
            }
        }
        /// <summary>
        /// 相识时的策略
        /// </summary>
        public class XiangshiStrategy : IChaseGirlStrategy
        {
            public void ChaseGirl()
            {
                Console.WriteLine("1.约女孩儿看电影");
                Console.WriteLine("2.约女孩儿吃饭");
            }
        }
        /// <summary>
        /// 相知时的策略
        /// </summary>
        public class XiangzhiStrategy : IChaseGirlStrategy
        {
            public void ChaseGirl()
            {
                Console.WriteLine("1.多送小礼物");
                Console.WriteLine("2.相约出去旅游");
            }
        }

    智囊

        /// <summary>
        /// 智囊
        /// </summary>
        public class BigThink
        {
            private IChaseGirlStrategy strategy;
            /// <summary>
            /// 策略模式和工厂模式结合
            /// </summary>
            /// <param name="type"></param>
            public BigThink(string type)
            {
                switch (type)
                {
                    case "1": strategy = new XiangjianStrategy(); break;
                    case "2": strategy = new XiangshiStrategy(); break;
                    case "3": strategy = new XiangzhiStrategy(); break;
                }
            }
            /// <summary>
            /// 获取策略
            /// </summary>
            public void GetStrategy()
            {
                strategy.ChaseGirl();
            }
        }

    客户端

    string[] flags = { "1", "2", "3" };
    Console.WriteLine("*************************************");
    Console.WriteLine("请选择所处阶段,获取相应策略");
    Console.WriteLine("【1】:相见时...");
    Console.WriteLine("【2】:相识时...");
    Console.WriteLine("【3】:相知时...");
    Console.WriteLine("*************************************");
    bool isRun = true;
    do
    {
        var flag = Console.ReadLine();
        if (flags.Contains(flag))
        {
            BigThink bigThink = new BigThink(flag);
            bigThink.GetStrategy();
            Console.WriteLine(".............................");
            Console.WriteLine("按上述指令之外按键退出...");
        }
        else
        {
            isRun = false;
        }
    
    } while (isRun);

    结果

    请多多指教~

  • 相关阅读:
    01
    Django2
    Django01
    DS18B20时序解析,以及读出85原因诠释
    python字符串打印-不同方法vars
    2.对象属性
    1.excel-vba-对象
    搭建 eclipse,maven,tomcat 环境
    jsp include flush true
    oracle数据库基础
  • 原文地址:https://www.cnblogs.com/sayook/p/9121978.html
Copyright © 2011-2022 走看看