Шаблон разработки стратегии и Factory Шаблон проектирования метода
Я начинаю изучать шаблоны проектирования. Теперь я понимаю немного, но для меня довольно много путаницы. Какая разница между стратегией DP и Factory методом DP? Для меня они оба выглядят одинаково.
Ответы
Ответ 1
Стратегия - это поведение. Factory о создании/установке.
Предположим, что у вас есть алгоритм, чтобы рассчитать процент скидки. У вас может быть 2 реализации этого алгоритма; один для постоянных клиентов, а другой для обычных клиентов.
Вы можете использовать стратегию DP для этой реализации: вы создаете интерфейс и 2 класса, которые реализуют этот интерфейс. В одном классе вы реализуете обычный алгоритм расчета скидок, в другом классе вы реализуете алгоритм "хороших клиентов".
Затем вы можете использовать шаблон Factory, чтобы создать экземпляр класса, который вы хотите. Таким образом, метод Factory представляет собой либо обычный алгоритм скидок для клиентов, либо другую реализацию.
Короче: метод Factory создает правильный класс; реализация стратегии содержит алгоритм, который должен быть выполнен.
Ответ 2
Стратегии инкапсулируют разные поведения за одним и тем же интерфейсом. Вы создаете стратегии с помощью оператора new
. Например (тот же бизнес-пример, что и Фредерик):
DiscountCalculator calc = new GoogCustomerDiscountCalculator();
Integer discount = calc.calculate();
Factory Метод инкапсулирует механизм создания экземпляра какого-либо другого интерфейса (возможно, Стратегия, но, возможно, что-то еще). Например:
DiscountFactory factory = new DiscountFactory();
DiscountCalculator calc = factory.getDiscountCalculator();
Integer discount = calc.calculate();
Стратегия часто используется вместе с методом Factory, а метод Factory часто используется для создания других стереотипов, а не только для стратегий.
Ответ 3
Разница заключается в их намерении:
Шаблон метода factory представляет собой шаблон creational, используемый для отсрочки создания объектов в подклассах. С другой стороны, шаблон стратегии - это поведенческий шаблон, используемый для отторжения алгоритма от клиентского кода.
Вы бы использовали первое, если вам нужно абстрактно создать объект, указав метод, возвращающий экземпляр определенного типа, но позволяя его реализовать. В 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.
С другой стороны, вы должны использовать шаблон стратегии, если вам нужно отделить алгоритм от вызывающего кода. Это похоже на то, как View взаимодействует с контроллером в шаблоне MVC. В гипотетическом java MVC UI kit это может быть следующим:
// 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. Таким образом, виджеты (представления) слабо связаны с логикой обработки действий (контроллерами).
Мы могли бы сделать что-то более интересным, смешав стратегию и шаблон метода factory вместе так:
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 по умолчанию).
Оба шаблона несколько похожи на то, что они откладывают часть логики в другое место. Это общая тема в шаблонах проектирования, которая позволяет разделять проблемы. Однако природа или намерение отложенной логики совершенно разные. factory метод вызывает логику создания подклассов (в моем примере - создание конкретных экземпляров ActionHandler), тогда как шаблон стратегии - выполнение алгоритма (в моем примере, что делать, когда пользователь взаимодействует с определенным компонентом).
Ответ 4
Вы можете найти другую реализацию Java для шаблона стратегии http://javabyranjith.blogspot.in/2017/04/strategy-design-pattern.html
и
factory шаблон проектирования метода при http://javabyranjith.blogspot.in/2014/06/factory-method-design-pattern.html