Стратегия (Strategy): выбор алгоритма во время выполнения


Стратегия также добавляет "Контекст", который может быть суррогатным классом, контролирующим выбор и использование определенной стратегии объекта - почти как Состояние! Вот как это выглядит:

//: strategy:StrategyPattern.java
package strategy;

import com.bruceeckel.util.*; // Arrays2.toString()

import junit.framework.*;

// Интерфейс стратегии:
interface FindMinima {
  
// Линия - это последовательность точек:
  
double[] algorithm(double[] line);
}

// Различные стратегии:
class LeastSquares implements FindMinima {
  
public double[] algorithm(double[] line) {
     
return new double[] { 1.1, 2.2 }; // Dummy
  
}
}

class NewtonsMethod implements FindMinima {
  
public double[] algorithm(double[] line) {
     
return new double[] { 3.3, 4.4 }; // Dummy
  
}
}

class Bisection implements FindMinima {
  
public double[] algorithm(double[] line) {
     
return new double[] { 5.5, 6.6 }; // Dummy
  
}
}

class ConjugateGradient implements FindMinima {
  
public double[] algorithm(double[] line) {
     
return new double[] { 3.3, 4.4 }; // Dummy
  
}
}

// "Контекст" управляет стратегией:
class MinimaSolver {
  
private FindMinima strategy;
  
  
public MinimaSolver(FindMinima strat) {
     
strategy = strat;
  
}
  
  
double[] minima(double[] line) {
     
return strategy.algorithm(line);
  
}
  
  
void changeAlgorithm(FindMinima newAlgorithm) {
     
strategy = newAlgorithm;
  
}
}

public class StrategyPattern extends TestCase {
  
MinimaSolver solver = new MinimaSolver(new LeastSquares());
  
double[] line = { 1.0, 2.0, 1.0, 2.0, -1.0, 3.0, 4.0, 5.0, 4.0 };
  
  
public void test() {
     
System.out.println(Arrays2.toString(solver.minima(line)));
      solver.changeAlgorithm
(new Bisection());
      System.out.println
(Arrays2.toString(solver.minima(line)));
  
}
  
  
public static void main(String args[]) {
     
junit.textui.TestRunner.run(StrategyPattern.class);
  
}
}
// /:~

Обратите внимание на сходство с шаблононным методом - шаблонный метод требует различия, так что он имеет более одного метода для вызова, что делает вещи фрагментированными. Однако есть большая вероятность, что объект стратегии будет иметь более одного вызываемого метода; рассмотрите систему выполнения заказов Shalloway с информацией страны в каждой стратегии.

Пример стратегии из JDK: сравнитель объектов.