第六篇 编排方法 第十八章 - 策略模式

  前文介绍的模板方法由若干抽象方法组合而成,抽象方法之间的关系主要是先后顺序关系。本章我们重点讨论方法之间的另一种关系——平行关系。
  同一份功能可以用不同的方法(或算法)实现,这些方法构成了平行关系,彼此可以相互替代,使用时只择取其中一个。
  怎么把一组平行的方法组织起来呢?
  枚举(enum)是个不错的选择。
  我们以小麦产量的预测方法为例进行说明。

// 产量预测方法
public enum Prediction {

  // 湿法预测
  WET {
    @Override
    public void predict() {}
  },
  // 干法预测
  DRY {
    @Override
    public void predict() {}
  };

  public abstract void predict();

}

// 测试类
public class Test {

  public void test() {
    Prediction.WET.predict();
  }

}

 “湿法预测”和“干法预测”呈平行关系,把它们放在枚举中,这种关系显得一目了然。
  大多数情况下,我们更希望将平行的方法分置在不同的类中,这样不仅很灵活,还会留出更多的扩展空间。策略模式就采用了这样的设计思路。
  来看例子。

// 上下文
public class Context {

  double m;// 单位面积穗数
  double n;// 穗粒数
  double t;// 千粒重
  double w;// 风干后的单位面积重量
  double s;// 种植面积
  double p;// 产量

  // 预测结果
  public double result() {
    return p;
  }

}

// 策略
public interface Strategy {

  public void predict(Context cxt);

}

// 湿法策略
public class WetStrategy implements Strategy {

  public void predict(Context cxt) {
    // 产量=单位面积穗数*穗粒数*千粒重*种植面积
  }

}

// 干法策略
public class DryStrategy implements Strategy {

  public void predict(Context cxt) {
    // 产量=风干后的单位面积重量*种植面积
  }

}

// 测试类
public class Test {

  public void test() {
    Context cxt = new Context();
    Strategy obj = new WetStrategy();
    obj.predict(cxt);
    cxt.result();
  }

}

  两个产量预测方法升级成了“湿法策略”和“干法策略”两个类。方法之间的关系变得松散,各自有了更大的用武空间。连接它们的纽带是“策略”接口,这是一个冠名意义上的接口,方便大家将其实现类识别为一组呈平行关系的算法。
  至此,两个方法之间的关系演变成了两个类之间的关系。
  关于类之间关系的更多内容,我们将在最后一个篇目展开讨论。

posted on 2025-03-23 22:37  星辰河岳  阅读(22)  评论(0)    收藏  举报