文章出處
完整策略模式單元測試類
文章列表
經典的策略模式如下圖所示:
讓我解釋一下這幅圖的含義,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 }
文章列表
全站熱搜