我开始学习设计模式。现在我有点明白了,但是还有很多困惑。 策略模式和工厂方法模式之间有什么区别?对我来说它们看起来都一样。
我开始学习设计模式。现在我有点明白了,但是还有很多困惑。 策略模式和工厂方法模式之间有什么区别?对我来说它们看起来都一样。
策略模式是关于行为的,工厂模式是关于创建/实例化的。
假设您有一个算法用于计算折扣百分比。您可以有两个实现该算法的版本:一个适用于普通客户,另一个适用于非常优秀的客户。
您可以使用策略设计模式来实现这个功能:创建一个接口和两个实现该接口的类。在一个类中,您实现了普通客户的折扣计算算法,在另一个类中,您实现了‘好客户’的算法。
然后,您可以使用工厂模式来实例化您想要的类。因此,工厂方法会实例化正常客户折扣算法或其他实现。
简而言之:工厂方法实例化正确的类;策略实现包含必须执行的算法。
策略模式通过相同的接口封装了不同的行为。您可以使用 new
操作符实例化策略。例如(与 Frederik 建议的相同业务案例):
DiscountCalculator calc = new GoogCustomerDiscountCalculator();
Integer discount = calc.calculate();
工厂方法封装了一些其他接口的实例化机制(可能是策略,但也可能是其他东西)。例如:
DiscountFactory factory = new DiscountFactory();
DiscountCalculator calc = factory.getDiscountCalculator();
Integer discount = calc.calculate();
策略模式通常与工厂方法一起使用,而工厂方法通常用于实例化其他原型,而不仅仅是策略。
两种模式的区别在于它们的意图:
工厂方法模式是一种创建型模式,用于将对象实例化延迟到子类。另一方面,策略模式是一种行为型模式,用于将算法与客户端代码解耦。
如果您需要通过定义返回特定类型实例的方法来抽象对象创建,并让子类实现它,则可以使用第一个。在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...
}
// 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);
}
}
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();
}
}