行为型模式:Strategy 策略模式

                                                      行为型模式:Strategy 策略模式

1、算法与对象的耦合
  对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...
 
2、动机(Motivation)
  1)在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
  2)如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
 
3、意图(Intent)
  定义一系列算法,把它们一个个封装起来,并且使它们可以互相替换。该模式使得算法可独立于使用它的客而变化。
                                                                                                        ——《设计模式》GoF
 
4、实例:物流管理
  1)一般做法
//枚举是一个变化点,可能增加D,E,F...
public enum CartType
{
  A,
  B,
  C,
}

public class Cart
{
  public void Process(CartType cartType)
  {
    //最简单的运行时变化就是if-else结构
    //枚举发生了变化,if-else也要相应的增加,并且要增加相应的处理方法
    if (cartType == CartType.A)
    {
      ProcessA();
    }
    else if (cartType == CartType.B)
    {
      ProcessB();
    }
    else if (cartType == CartType.C)
    {
      ProcessB();
    }
  }
 
  //下面的方法都可以发生变化
  protected virtual void ProcessA()
  {
    //...
  }
 
  protected virtual void ProcessB()
  {
    //...
  }
 
  protected virtual void ProcessC()
  {
    //...
  }
}

  2)重构得到Strategy设计模式
//接口:表达算法抽象,而不用抽象类
public interface IProcessStrategy
{
  void Process1();
  void Process2();
  ......
}

//每一个子类都是一个算法,一般不写在同一个文件里
public class ProcessStrategyA : IProcessStrategy
{
  public void Process1()
  {
  }
  ......
}

public class ProcessStrategyB : IProcessStrategy
{
  public void Process1()
  {
  }
  ......
}

public class ProcessStrategyC : IProcessStrategy
{
  public void Process1()
  {
  }
  ......
}

//...... : IProcessStrategy

public class Cart()
{
  //对象组合:组合一个算法的抽象
  IProcessStrategy processStrategy;
 
  //可以使用工厂模式生成IProcessStrategy对象
  public Cart(IProcessStrategy processStrategy)
  {
    this.processStrategy = processStrategy;
  }
 
  public void SomeMethod1()
  {
    //...
    processStrategy.Process1();
  }
 
  public void SomeMethod2()
  {
    //...
    processStrategy.Process2();
  }
 
  ......
}

//客户
public class App
{
  public static void Main()
  {
    //这里是动态new一个对像,但是可以看成是动态得到一个方法或一组方法
    Cart cart = new Cart(new ProcessStrategyC());
    cart.SomeMethod1();
    .....
  }
}

5、Strategy模式的几个要点
  1)Strategy及其子类为组件提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换。所谓封装算法,支持算法的变化。
  2)Strategy模式提供了用条件判断语句以外的另一种选择,消除条件判断语句,就是在解耦合。含有许多条件判断语句的代码通常都需要Strategy模式。
  3)与State类似,如查Strategy对象没有实例变量,那么各个上下文可以共享同一个Strategy对象,从而节省对象开销。
 
6、Strategy模式.NET框架的应用:ArrayList.Sort()排序
//坐标类
public class MyPoint()
{
  private int x;
  private int y;
 
  public MyPoint(int X, int Y)
  {
    this.x = X;
    this.y = Y;
  }
}

//现在要对坐标排序,但是这个类不支持排序
//IComparer接口相当于以上实例的IProcessStrategy类,说明它应用了策略模式
public class PointComparerA : IComparer
{
  public int Compare(object objA, object objB)
  {
    //根据点与原点的距离排序
  }
}

public class PointComparerB : IComparer
{
  public int Compare(object objA, object objB)
  {
    //根据x坐标排序
  }
}

public class PointComparerC : IComparer
{
  public int Compare(object objA, object objB)
  {
    //根据y坐标排序
  }
}
......

public class App
{
  public static void Main()
  {
    ArrayList list = new ArrayList();
    list.Add(new MyPoint());
    list.Add(new MyPoint());
    list.Add(new MyPoint());
    list.Add(new MyPoint());
    list.Add(new MyPoint());
   
    list.Sort(new PointComparerA());
    //这里的Sort()方法相当于以上实例的Cart类
  }
}

你可能感兴趣的:(行为型模式:Strategy 策略模式)