工厂模式和策略模式之间有什么区别?


Answers:


226

工厂模式是一种创造模式。战略模式是一种运营模式。换句话说,工厂模式用于创建特定类型的对象。策略模式用于以特定方式执行一个操作(或一组操作)。在经典示例中,工厂可能会创建不同类型的动物:狗,猫,老虎,而策略模式将执行特定的动作,例如,移动;使用“跑步”,“步行”或“移动”策略。

实际上,两者可以一起使用。例如,您可能有一个创建业务对象的工厂。它可能基于持久性介质使用不同的策略。如果您的数据以XML本地存储,则将使用一种策略。如果数据在另一个数据库中是远程的,它将使用另一个数据库。


1
`策略模式用于以特定方式执行一个操作(或一组操作)`这是否意味着对对象进行操作?
OPV

32

策略模式允许您多态地更改类的行为。

工厂模式允许您封装对象创建。

加里提出了一个很好的观点。如果您使用的是编码而不是“ concretions”的抽象原理,那么很多模式看起来就像是主题的变体。


25

只是补充了tvanfosson所说的,就实现而言,许多模式看起来都是相同的。也就是说,您需要创建很多接口,而在代码中可能以前没有一个接口,然后创建了该接口的许多实现。它们的目的和使用方式不同。


13
  • 工厂(方法)模式。

仅创建具体实例。不同的参数可能导致不同的对象。这取决于逻辑等。

  • 策略模式。

封装算法(步骤)以执行操作。因此,您可以更改策略并使用其他算法。

尽管两者看起来非常相似,但目的却截然不同,一个目的是创建另一个目的是执行一个动作。

所以。如果您的Factory方法是固定的,则可能会这样:

 public Command getCommand( int operatingSystem ) { 
      switch( operatingSystem ) { 
           case UNIX    :
           case LINUX   : return new UnixCommand();
           case WINDOWS : return new WindowsCommand();
           case OSX     : return new OSXCommand();
       }
  }

但是,假设您的工厂需要更高级或动态的创建。您可以在不重新编译的情况下将策略添加到工厂方法中并对其进行更改,该策略可以在运行时更改。


我认为您在这里没有提出正确的观点。首先,这些模式的原因之一是避免有利于多态性的条件。首先必须在简单工厂和抽象工厂之间进行区别。d第一个是简单工厂,其中只有一个类充当对象创建工厂,而在后者中,您连接到接口然后调用实现该接口的不同工厂,应该根据某些标准对同一方法进行不同的实现。(续)
interboy

4
正是在这种情况下,它导致了一种策略模式,但是从语义上来说与它不同,因为它用于对象创建而不是操作。因此,基本上,您可以使用不同的策略来创建对象。
interboy

2
@OscarRyz您能用描述两者的程序来更新您的答案吗
Prakash Pandey

11

首先,必须在简单工厂和抽象工厂之间进行区分。第一个是简单工厂,其中只有一个类充当对象创建工厂,而在后一个工厂中,您连接到工厂接口(定义方法名称),然后调用实现该接口的不同工厂,基于某些标准,应该具有相同方法的不同实现。例如,我们有一个ButtonCreationFactory接口,它由两个工厂实现,第一个工厂WindowsButtonCreationFactory(创建具有Windows外观的按钮),第二个LinuxButtonCreationFactory(创建具有Linux外观的按钮)。因此,这两个工厂确实具有相同的创建方法,但实现方式(算法)不同。

例如,如果您想要具有Linux外观的按钮:

ButtonCreationFactory myFactory = new LinuxButtonCreationFactory();
Button button1 = myFactory.createButton(...);

或者如果您想要Windows按钮

ButtonCreationFactory myFactory = new WindowsButtonCreationFactory();
Button button1 = myFactory.createButton(...);

正是在这种情况下,由于它区分了进行某些创建的算法,因此它会导致一种策略模式。但是,它在语义上与它不同,因为它用于对象创建而不是操作算法。因此,基本上,对于抽象工厂,您可以使用不同的策略来创建对象,这使其与策略模式非常相似。但是AbstractFactory是创新的,而Strategy模式是可操作的。在实施方面,它们的结果是相同的。


10

工厂(以及工厂返回的FactoryMethod)

  1. 创作模式
  2. 基于继承
  3. 工厂返回一个工厂方法(接口),该方法又返回具体对象
  4. 您可以将新的具体对象替换为接口,并且客户端(调用方)不应了解所有具体实现
  5. 客户端始终仅访问界面,并且可以在Factory方法中隐藏对象创建详细信息

看看这篇维基百科文章javarevisitited文章

策略模式:

  1. 这是一种行为模式
  2. 基于委托
  3. 它通过修改方法行为来改变对象的胆量
  4. 用于在一系列算法之间切换
  5. 它在运行时更改对象的行为

例:

您可以为特定项目(飞机票或ShoppingCart项目)配置折扣策略。在此示例中,您将在7月-12月期间为该商品提供25%的折扣,而在1月-6月期间对该商品没有折扣。

相关文章:

战略模式的真实例子

设计模式:工厂vs工厂方法vs抽象工厂


3

扩展一下奥斯卡所说的内容并参考他的代码:

getCommand是Factory,而UnixCommand,WindowsCommand和OSXCommand类是Strategies。


3

简单来说,策略模式更多是在行为的运行时创建,而您无需关心实现类。另一方面,工厂是在运行时创建具体的类实例,并且您可以使用已实现的接口公开的任何行为(方法)。


2

您不能仅通过查看代码或分类来了解差异。要正确掌握GoF模式,请寻找它们的意图:

策略:“定义一组算法,封装每个算法,并使它们可互换。策略使算法独立于使用该算法的客户端而变化。”

工厂方法:“定义用于创建对象的接口,但是让子类决定实例化哪个类。工厂方法使类将实例化推迟到子类。”

这是关于这两种模式的意图和差异的详尽解释:工厂方法和策略设计模式之间的差异


1

我可能会与Oscar脱口而出,因为他关于Factory实现的示例是紧密耦合且非常封闭的,难怪您选择的是Strategy模式。Factory实现不应依赖于实例化的固定数量的特定类,例如:

public Command getCommand( int operatingSystem ) {        
   return commandTable.get(operatingSystem); 
}

...

public class WindowsCommand implements Command {
    ...
    static {
        CommandTable.getInstance().registerCommand(WIN_COMMAND_ID, new WindowsCommand());
    }

}

我想选择一个或另一个的最合适标准主要是您用来命名类和方法的术语,同时考虑到我们所有人都应该倾向于接口而不是类,还应着眼于目标:我们旨在确定哪些代码将在运行时执行。也就是说,我们可以通过使用两种模式中的任何一种来实现目标。


1

策略和工厂是不同的目的。在策略中,您已定义了方法,使用此模式,您可以互换行为(算法)。来到工厂,周围会有很多变化。但是来自GO4的原始模式指出工厂将对象的创建留给了子类。在这里,您将使用工厂替换完整的实例,而不是您感兴趣的行为。这样,您将替换完整的系统而不是算法。


0

工厂模式是一种创建模式,使用指定的属性(行为)创建。在创建后的运行时,您不会更改其属性(行为)。因此,如果您需要其他属性(行为),则必须删除该对象并创建具有所需属性(行为)的新对象。这不是傻瓜。而在使用策略模式的情况下,您可以在运行时更改属性(行为)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.