我开始学习设计模式.现在我理解了一点,但对我来说有很多困惑.策略DP和工厂方法DP有什么区别?对我来说,他们看起来都一样.
Fre*_*els 51
战略是关于行为.工厂是关于创造/安置.
假设您有一个算法来计算折扣百分比.您可以拥有该算法的2个实现; 一个用于普通客户,一个用于超常普通客户.
您可以将策略DP用于此实现:您创建一个接口,以及两个实现该接口的类.在一个类中,您实现常规折扣计算算法,在另一个类中实现"良好客户"算法.
然后,您可以使用工厂模式来实例化所需的类.因此,工厂方法实例化常规客户折扣算法或其他实现.
简而言之:工厂方法实例化正确的类; 策略实现包含必须执行的算法.
yeg*_*256 11
策略包含同一界面背后的不同行为.您使用new运算符实例化策略.例如(与Frederik建议的相同的商业案例):
DiscountCalculator calc = new GoogCustomerDiscountCalculator();
Integer discount = calc.calculate();
Run Code Online (Sandbox Code Playgroud)
Factory Method包含其他一些接口的实例化机制(可能是策略,但也许是其他的).例如:
DiscountFactory factory = new DiscountFactory();
DiscountCalculator calc = factory.getDiscountCalculator();
Integer discount = calc.calculate();
Run Code Online (Sandbox Code Playgroud)
策略模式通常与工厂方法一起使用,而工厂方法通常用于其他构造型的实例化,而不仅仅是策略.
不同之处在于他们的意图:
工厂方法模式是用于将对象实例化推迟到子类的创建模式.另一方面,策略模式是用于将算法与客户端代码分离的行为模式.
如果需要通过定义返回特定类型的实例的方法来抽象对象创建,那么您将使用第一个,但让子类实现它.在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...
}
Run Code Online (Sandbox Code Playgroud)
注意实际对象实例化与SomeAbstractClass的实现有何不同.
另一方面,如果需要将算法与调用代码分离,则可以使用策略模式.这类似于View在MVC模式中与Controller通信的方式.在假设的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,假设您有另一个组件,而不是单击响应滑动(即滑块)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
注意在Button和Slider类(视图)中执行动作的逻辑是如何完全相同的(都遵循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());
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用策略模式,我们可以简单地通过使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是策略模式的说明性示例,而不是如何实现Swing(Java的默认UI工具包).
两种模式都有些相似,因为它们将某些逻辑推迟到其他地方.这是设计模式中的一个共同主题,可以分离关注点.但是,延迟逻辑的性质或意图是完全不同的.工厂方法将创建逻辑推迟到子类(在我的示例中,创建具体的ActionHandler实例),而策略模式执行算法(在我的示例中,当用户与特定组件交互时该怎么做).