区别在于他们的意图:
工厂方法模式是一种创造性的模式,用于将对象实例化推迟到子类。另一方面,策略模式是一种行为模式,用于将算法与客户端代码分离。
如果您需要通过定义一个返回特定类型实例的方法来抽象对象创建,您将使用第一个,但让子类实现它。在 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 模式中 View 与 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);
}
}
现在,假设您有另一个组件,而不是单击响应滑动(即滑块)
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 类(视图)中,执行动作的逻辑是完全相同的(都遵循 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 工具包)的实现方式。
这两种模式有些相似之处在于它们将某些逻辑推迟到其他地方。这是实现关注点分离的设计模式中的一个常见主题。但是,延迟逻辑的性质或意图是完全不同的。工厂方法将创建逻辑推迟到子类(在我的示例中,具体 ActionHandler 实例的创建),而策略模式则执行算法(在我的示例中,当用户与特定组件交互时要做什么)。