策略模式(Strategy Pattern) 中体现了两个非常基本的面向对象设计原则
1.封装变化概念.
2.编程中使用接口,而不是对接口实现.换句话说就是面向接口编程.
策略模式的定义
1.定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换.
2.StrategyPattern使这些算法在客户端调用它们的时候能够互不影响变化.
比如:完成某件事情的方法有多种,这多种方法都可以完成这件事情,假设我想去
机场,那么去机场有多种方式:打车去,坐公交车去,开车去,骑车去等等.这几种
方式都可以实现我的目的,但是它们具体的实现方式是不一样的,但是它们的目的
是一样的.将这些不一样的东西叫做一组算法,它们可以互相交换达到同样的目的.
策略模式的意义
1.策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之
间是弱连接的关系也就是高内聚,低耦合:(模块内部它们是互相关联的,它们要达到高内聚,
就是说联系的非常紧密,但是模块与模块之间它们是达到低耦合,它们的关联不是那么
强)
2.弱连接的特性使软件具有更强的可扩展性,易于维护;更重要的是,它大大提高了软
件的可重用性.
策略模式的组成
抽象策略角色:策略类,通常由一个接口或者抽象类实现
具体策略角色:包装了相关算法和行为
环境角色:持有一个策略类(抽象策略角色)的引用,最终给客户端调用.也就是说客户端
使用的是环境角色但是环境角色中有个抽象策略角色的一个引用,这样在客户端使用的
时候我就可以去替换,相应的具体策略角色.
策略模式的实现
1.策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而
使得他们可以互相替换.
2.策略模式使得算法可以再不影响到客户端的情况下发生变化.使用策略模式可以把行为
和环境分割开来.
3.环境类负责维持和查询行为类,各种算法则在具体策略模式中提供.由于算法和环境独立
开来,算法的修改都不会影响环境和客户端.
策略模式的缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类.
2.造成很多的策略类.
克服这个缺点---->采用工厂方法
ClassDiagrm:
SequenceDiagrm:
class Client { static void Main(string[] args) { Context context = new Context(); context.Add(10); context.Add(7); context.Add(-3); context.Add(9); context.Strategy = new QuickSortStrateqy(); context.Sort(); context.Display(); context.Strategy = new BubbleSortStrategy(); context.Sort(); context.Display(); Console.ReadKey(); } } /// <summary> /// 环境角色 /// </summary> public class Context { List<int> list = new List<int>(); Strategy strategy; public Strategy Strategy { set { strategy = value; } get { return strategy; } } public void Add(int i) { list.Add(i); } public void Sort() { strategy.Sort(list); } public void Display() { foreach (int i in list) { Console.WriteLine(i); } } } /// <summary> /// 抽象策略角色 /// </summary> public interface Strategy { void Sort(List<int> list); } /// <summary> /// 具体策略角色 /// </summary> public class QuickSortStrateqy : Strategy { public void Sort(List<int> list) { //Sort()方法内部使用快速排序 list.Sort(); } } /// <summary> /// 具体策略角色 /// </summary> public class BubbleSortStrategy : Strategy { /*冒泡排序有个特点当某一轮比较完之后,如果没有一个元素位置发生变化, 表示排序实际上已经结束了.因此在排序的时候我们应该设置一个bool值 看看元素有没发生交换.*/ public void Sort(List<int> list) { for (int i = 0; i < list.Count; i++) { bool flag = false; for (int j = 0; j < list.Count - 1 - i; j++) { if (list[j] > list[j + 1]) { list[j] = list[j] + list[j + 1]; list[j + 1] = list[j] - list[j + 1]; list[j] = list[j] - list[j + 1]; flag = true; } } if (!flag) { break; } } } }