zoukankan      html  css  js  c++  java
  • 策略模式

    经典的策略模式如下图所示:

    image

    让我解释一下这幅图的含义,IContext是上下文的接口类,IStrategy是策略的接口,IStrategy依赖于IContext,也就是IContext里面存有一个IStrategy的策略字段。

    其实策略模式说白了,就像诸葛亮给刘备的锦囊妙计一样,遇到一种具体的情况,采取一种相应的策略。也就像我们平时会观察天气,根据今天有没有下雨,选择要不要打伞,下雨的话,那么打伞;不下雨就不打伞。

    下面我们用代码来演示一下经典的策略模式。我们将要做的是,从一个数组中提取一个值,这个值的提取要根据用户的选择,也就是我们要根据用户的选择提取对应的值。假设用户有三种选择,选最大值,最小值,选第一个值。

    1、首先我们要实现公共接口

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace BangWorks.PractcalPattern.StategyPattern.Classic
    {
        interface IStrategy
        {
            /// <summary>
            /// 按照算法的要求,将数据提取出来
            /// </summary>
            /// <param name="Data">数组</param>
            /// <returns></returns>
            int PickUp(int[] Data);
        }
        interface IContext
        {
            IStrategy Strategy { get; set; }
            int GetData(int[] data);
            
        }
    }

    2、实现相应的策略类

    /// <summary>
            /// 取最大值
            /// </summary>
            class DescentSortStrategy:IStrategy
            {
                int IStrategy.PickUp(int[] Data)
                {   Array.Sort<int>(Data);
                    return Data[Data.Length-1];
                  
                }
            }
            /// <summary>
            /// 取第一个值
            /// </summary>
            class FirstDataStrategy:IStrategy
            {
    
                public int PickUp(int[] Data)
                {
                    return Data[0];
                }
            }
            /// <summary>
            /// 取最小值
            /// </summary>
            class AscentStrategy:IStrategy
            {
                int IStrategy.PickUp(int[] Data)
                {
                    Array.Sort<int>(Data);
                    return Data[0];
                }
            }

    3、最后,我们利用策略模式来切换策略

    /// <summary>
            ///GetData 的测试
            ///</summary>
            [TestMethod()]
            public void GetDataTest()
            {
                IStrategy mStrategy = new FirstDataStrategy();
                
                IContext target = CreateIContext(); 
                int[] data = new int[]{7,2,5,8,0,1};
    
                //切换成取第一个值的
                target.Strategy = mStrategy;
                int expected = 7; 
                int actual;
                actual = target.GetData(data);
                Assert.AreEqual(expected, actual);
                //切换成取最小值的
                target.Strategy = new AscentStrategy();
                expected = 0; 
                actual = target.GetData(data);
                Assert.AreEqual(expected, actual);
    
                //切换成取最大值的
                target.Strategy = new DescentSortStrategy();
                expected = 8;
                actual = target.GetData(data);
                Assert.AreEqual(expected, actual);
            }

    最后附上完整的单元测试类

      1 using BangWorks.PractcalPattern.StategyPattern.Classic;
      2 using Microsoft.VisualStudio.TestTools.UnitTesting;
      3 using System;
      4 
      5 namespace BangWork.PractcalPattern.Concept.InderTest
      6 {
      7     
      8     
      9     /// <summary>
     10     ///这是 IContextTest 的测试类,旨在
     11     ///包含所有 IContextTest 单元测试
     12     ///</summary>
     13     [TestClass()]
     14     public class IContextTest:IContext
     15     {
     16         /// <summary>
     17         /// 取最大值
     18         /// </summary>
     19         class DescentSortStrategy:IStrategy
     20         {
     21             int IStrategy.PickUp(int[] Data)
     22             {   Array.Sort<int>(Data);
     23                 return Data[Data.Length-1];
     24               
     25             }
     26         }
     27         /// <summary>
     28         /// 取第一个值
     29         /// </summary>
     30         class FirstDataStrategy:IStrategy
     31         {
     32 
     33             public int PickUp(int[] Data)
     34             {
     35                 return Data[0];
     36             }
     37         }
     38         /// <summary>
     39         /// 取最小值
     40         /// </summary>
     41         class AscentStrategy:IStrategy
     42         {
     43             int IStrategy.PickUp(int[] Data)
     44             {
     45                 Array.Sort<int>(Data);
     46                 return Data[0];
     47             }
     48         }
     49         private TestContext testContextInstance;
     50 
     51         /// <summary>
     52         ///获取或设置测试上下文,上下文提供
     53         ///有关当前测试运行及其功能的信息。
     54         ///</summary>
     55         public TestContext TestContext
     56         {
     57             get
     58             {
     59                 return testContextInstance;
     60             }
     61             set
     62             {
     63                 testContextInstance = value;
     64             }
     65         }
     66 
     67         #region 附加测试特性
     68         // 
     69         //编写测试时,还可使用以下特性:
     70         //
     71         //使用 ClassInitialize 在运行类中的第一个测试前先运行代码
     72         //[ClassInitialize()]
     73         //public static void MyClassInitialize(TestContext testContext)
     74         //{
     75         //}
     76         //
     77         //使用 ClassCleanup 在运行完类中的所有测试后再运行代码
     78         //[ClassCleanup()]
     79         //public static void MyClassCleanup()
     80         //{
     81         //}
     82         //
     83         //使用 TestInitialize 在运行每个测试前先运行代码
     84         //[TestInitialize()]
     85         //public void MyTestInitialize()
     86         //{
     87         //}
     88         //
     89         //使用 TestCleanup 在运行完每个测试后运行代码
     90         //[TestCleanup()]
     91         //public void MyTestCleanup()
     92         //{
     93         //}
     94         //
     95         #endregion
     96 
     97 
     98         internal virtual IContext CreateIContext()
     99         {
    100             // TODO: 实例化相应的具体类。
    101             IContext target = new IContextTest();
    102             return target;
    103         }
    104 
    105         /// <summary>
    106         ///GetData 的测试
    107         ///</summary>
    108         [TestMethod()]
    109         public void GetDataTest()
    110         {
    111             IStrategy mStrategy = new FirstDataStrategy();
    112             
    113             IContext target = CreateIContext(); 
    114             int[] data = new int[]{7,2,5,8,0,1};
    115 
    116             //切换成取第一个值的
    117             target.Strategy = mStrategy;
    118             int expected = 7; 
    119             int actual;
    120             actual = target.GetData(data);
    121             Assert.AreEqual(expected, actual);
    122             //切换成取最小值的
    123             target.Strategy = new AscentStrategy();
    124             expected = 0; 
    125             actual = target.GetData(data);
    126             Assert.AreEqual(expected, actual);
    127 
    128             //切换成取最大值的
    129             target.Strategy = new DescentSortStrategy();
    130             expected = 8;
    131             actual = target.GetData(data);
    132             Assert.AreEqual(expected, actual);
    133         }
    134 
    135         /// <summary>
    136         ///Strategy 的测试
    137         ///</summary>
    138         [TestMethod()]
    139         public void StrategyTest()
    140         {
    141             IContext target = CreateIContext(); // TODO: 初始化为适当的值
    142             IStrategy expected = null; // TODO: 初始化为适当的值
    143             IStrategy actual;
    144             target.Strategy = expected;
    145             actual = target.Strategy;
    146             Assert.AreEqual(expected, actual);
    147             Assert.Inconclusive("验证此测试方法的正确性。");
    148         }
    149 
    150         public IStrategy Strategy
    151         {
    152             get;
    153             set;
    154         }
    155 
    156         public int GetData(int[] data)
    157         {
    158             return this.Strategy.PickUp(data);
    159         }
    160     }
    161 }
    完整策略模式单元测试类
  • 相关阅读:
    C++中虚函数
    ES6入门四:对象字面量扩展与字符串模板字面量
    ES6入门三:解构
    ES6入门二:默认值与默认值表达式
    ES6入门一:块级作用域(let&const)、spread展开、rest收集
    JavaScript严格模式
    JavaScript中with不推荐使用,为什么总是出现在面试题中?
    ES6入门一:ES6简介及Babel转码器
    HTML5之websocket
    HTML5之fileReader异步读取文件及文件切片读取
  • 原文地址:https://www.cnblogs.com/kissazi2/p/3285395.html
Copyright © 2011-2022 走看看