Шаблон проектирования стратегии и шаблон проектирования метода фабрики - PullRequest
14 голосов
/ 21 марта 2011

Я начинаю изучать шаблоны проектирования.Теперь я немного понимаю, но у меня много путаницы.В чем разница между Стратегия DP и Заводской метод DP ?Для меня они оба выглядят одинаково.

Ответы [ 4 ]

51 голосов
/ 21 марта 2011

Стратегия - это поведение. Фабрика о создании / создании.

Предположим, у вас есть алгоритм для расчета процента скидки. Вы можете иметь 2 реализации этого алгоритма; один для постоянных клиентов и один для необычных хороших клиентов.
Для этой реализации вы можете использовать стратегический DP: вы создаете интерфейс и 2 класса, которые реализуют этот интерфейс. В одном классе вы реализуете обычный алгоритм расчета скидки, в другом - алгоритм «хороших клиентов».

Затем вы можете использовать фабричный шаблон для создания экземпляра нужного вам класса. Таким образом, фабричный метод создает экземпляр обычного алгоритма скидок клиента или другой реализации.

Вкратце: фабричный метод создает правильный класс; реализация стратегии содержит алгоритм, который должен быть выполнен.

11 голосов
/ 21 марта 2011

Стратегии инкапсулируют различные варианты поведения за одним и тем же интерфейсом. Вы создаете стратегии с помощью оператора new. Например (тот же бизнес-кейс, что предложил Фредерик):

DiscountCalculator calc = new GoogCustomerDiscountCalculator();
Integer discount = calc.calculate();

Factory Method инкапсулирует механизм создания экземпляров какого-либо другого интерфейса (возможно, Стратегия, но может быть что-то еще). Например:

DiscountFactory factory = new DiscountFactory();
DiscountCalculator calc = factory.getDiscountCalculator();
Integer discount = calc.calculate();

Шаблон стратегии часто используется вместе с Фабричным методом, тогда как Фабричный метод часто используется для реализации других стереотипов, а не только Стратегий.

5 голосов
/ 04 сентября 2012

Разница в их намерении :

Шаблон фабричного метода - это творческий шаблон, используемый для переноса создания экземпляров объекта на подклассы. С другой стороны, шаблон стратегии - это поведенческий шаблон, используемый для отделения алгоритма от клиентского кода.

Вы бы использовали первое, если вам нужно абстрагировать создание объекта, определив метод, который возвращает экземпляр определенного типа, но позволяя подклассам реализовать его. В Java пример будет следующим:

public interface SomeAbstractObject {
   // methods...
}

public abstract class SomeAbstractClass {
  public abstract SomeAbstractObject newSomeObject();
  // Other methods...
}

public class SomeConcreteClassA extends SomeAbstractClass {
  public SomeAbstractObject newSomeObject() {
    // assuming SomeConcreteObjectA extends from SomeAbstractObject
    return new SomeConcreteObjectA();
  }
  // Other methods...
}

public class SomeConcreteClassB extends SomeAbstractClass {
  public SomeAbstractObject newSomeObject() {
    // assuming SomeConcreteObjectB extends form SomeAbstractObject
    return new SomeConcreteObjectB();
  }
  // Other methods...
}

Обратите внимание, как конкретная реализация объекта отличается от реализации SomeAbstractClass.

С другой стороны, вы бы использовали шаблон Стратегии, если вам нужно отделить алгоритм от вызывающего кода. Это похоже на то, как представление связывается с контроллером в шаблоне MVC. В гипотетическом наборе java MVC UI это может быть следующим:

// interface abstracting the algorithm of a user interaction with your ui components.
public interface ActionHandler {
   public void handle(Action a);
}

// concrete implementation of button clicked algorithm.
public class ButtonClickedHandler implements ActionHandler {
   public void handle(Action a) {
      // do some fancy stuff...
   }
}

public class Button extends Widget {

   // ActionHandler abstracts the algorithm of performing an action.
  private ActionHandler handler = new ButtonClickedHandler();

  // Delegates to the action handler to perform the action.
  public void execute(Action a) {
    handler.handle(a);
  }
}

Теперь предположим, что у вас есть другой компонент, который вместо нажатия реагирует на скольжение (т. Е. Слайдер)

public class Slider extends Widget {

  // SliderMovedHandler extends ActionHandler
  private ActionHandler handler = new SliderMovedHandler()

  // Delegates to action handler to perform the action.
  public void execute(Action a) {
    handler.handle(a);
  }
}

Обратите внимание, что в классах Button и Slider (Views) логика выполнения действия абсолютно одинакова (оба относятся к ActionHandler). Поэтому мы могли бы перетащить их в родительский класс (Widget) и позволить подклассам просто определить реализацию обработчика действия, например:

public class Widget {
  private ActionHandler handler;

  public Widget(ActionHandler handler) {
    this.handler = handler;
  }

  public void execute(Action a) {
    handler.handle(a);
  }
}

// concrete widget implementations change their behavior by configuring
// different action handling strategies.

public class Button extends Widget {
  public Button() {
    super(new ButtonClickedHandler());
  }
}

public class Slider extends Widget {
  public Slider() {
    super(new SliderMovedHandler());
  }
}

Используя шаблон стратегии, мы можем изменить поведение нашего виджета, просто настроив его в другой конкретной реализации ActionHandler. Таким образом, виджеты (представления) являются слабо связанной логикой обработки действий формы (контроллеры).

Мы могли бы сделать вещи немного интереснее, смешав стратегию и шаблон фабричного метода, например:

public abstract class Widget {

  public void execute(Action a) {
    // action handling strategy is retrieved by a factory method
    ActionHandler handler = getActionHandler();
    handler.handle(a);
  }

  // factory method defers creation of action handling strategy to subclasses
  public abstract ActionHandler getActionHandler();
}

// factory method defines different action handling strategy for different subclass

public class Button extends Widget {
   public ActionHandler getActionHandler() {
     return new ButtonClickedHandler();
   }
}

public class Slider extends Widget {
   public ActionHandler getActionHandler() {
     return new SliderMovedHandler();
   }
}

Обратите внимание, что это иллюстративный пример шаблона стратегии, а НЕ то, как реализован Swing (Java UI kit по умолчанию).

Обе модели несколько похожи в том, что они откладывают какую-то часть логики куда-то еще. Это общая тема в шаблонах проектирования, которая позволяет разделить проблемы. Однако природа или намерение отложенной логики совершенно иная. Метод Factory откладывает логику создания на подклассы (в моем примере - создание конкретных экземпляров ActionHandler), тогда как стратегия - на выполнение алгоритма (в моем примере, что делать, когда пользователь взаимодействует с конкретным компонентом).

1 голос
/ 06 апреля 2017

Вы можете найти другую реализацию Java для шаблона стратегии на http://javabyranjith.blogspot.in/2017/04/strategy-design-pattern.html

и

шаблон проектирования фабричного метода на http://javabyranjith.blogspot.in/2014/06/factory-method-design-pattern.html

...