策略模式结构:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace DesignPattern.BehavioralPattern
7 {
8 #region 策略模式
9 //定义:它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
10 //
11 //应用场景:
12 //1.当你想使用对象中各种不同的算法变体, 并希望能在运行时切换算法时
13 //2.有许多仅在执行某些行为时略有不同的相似类时,可以将不同行为抽取到一个独立类层次结构中,
14 // 并将原始类组合成同一个, 从而减少重复代码。
15 //3.如果算法在上下文的逻辑中不是特别重要, 使用该模式能将类的业务逻辑与其算法实现细节隔离开来。
16 //4.使用了复杂条件运算符以在同一算法的不同变体中切换时, 可使用该模式。
17 // 所有继承自同样接口的算法抽取到独立类中, 因此不再需要条件语句
18
19 /*实现方式:
20 1.从上下文类中找出修改频率较高的算法 (也可能是用于在运行时选择某个算法变体的复杂条件运算符)。
21
22 2.声明该算法所有变体的通用策略接口。
23
24 3.将算法逐一抽取到各自的类中, 它们都必须实现策略接口。
25
26 4.在上下文类中添加一个成员变量用于保存对于策略对象的引用。 然后提供设置器以修改该成员变量。
27 上下文仅可通过策略接口同策略对象进行交互, 如有需要还可定义一个接口来让策略访问其数据。
28
29 5.客户端必须将上下文类与相应策略进行关联, 使上下文可以预期的方式完成其主要工作。
30 */
31 #endregion
32
33 //策略 (Strategy) 接口是所有具体策略的通用接口, 它声明了一个上下文用于执行策略的方法。
34 public interface IStrategy
35 {
36 void DoBussnessLogic(List<string> orderList);
37 }
38
39 //具体策略 (Concrete Strategies) 实现了上下文所用算法的各种不同变体。
40 public class ConcreteStrategy : IStrategy
41 {
42 public void DoBussnessLogic(List<string> orderList)
43 {
44 if (orderList.Count > 1)
45 {
46 orderList.Sort();
47 }
48 }
49 }
50
51 public class ReverseStrategy : IStrategy
52 {
53 public void DoBussnessLogic(List<string> orderList)
54 {
55 if (orderList.Count > 1)
56 {
57 orderList.Sort();
58 orderList.Reverse();
59 }
60 }
61 }
62
63 //上下文 (Context) 维护指向具体策略的引用, 且仅通过策略接口与该对象进行交流。
64 public class StrategyContext
65 {
66 IStrategy _strategy;
67 public StrategyContext(IStrategy strategy)
68 {
69 _strategy = strategy;
70 }
71
72 public void SetStrategy(IStrategy strategy)
73 {
74 _strategy = strategy;
75 }
76
77 // 当上下文需要运行算法时, 它会在其已连接的策略对象上调用执行方法。
78 // 上下文不清楚其所涉及的策略类型与算法的执行方式。
79 public string OrderList(List<string> list)
80 {
81 _strategy.DoBussnessLogic(list);
82 string result = null;
83 foreach (var item in list)
84 {
85 result += $"{item},";
86 }
87 Console.WriteLine(result);
88 return result;
89 }
90 }
91
92 //客户端 (Client) 会创建一个特定策略对象并将其传递给上下文。
93 //上下文则会提供一个设置器以便客户端在运行时替换相关联的策略。
94 public class StrategyClient
95 {
96 public static void Test()
97 {
98 ConcreteStrategy strategy = new ConcreteStrategy();
99 StrategyContext context = new StrategyContext(strategy);
100 List<string> list = new List<string>() { "a", "c", "b", "d" };
101 context.OrderList(list);
102
103 ReverseStrategy reverse = new ReverseStrategy();
104 context.SetStrategy(reverse);
105 context.OrderList(list);
106 }
107
108 }
109 }