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

IT小君   2021-11-06T00:30:24

任何人都可以解释工厂模式和策略模式之间的区别吗?

对我来说,除了一个额外的工厂类(它在工厂模式中创建一个产品对象)之外,两者看起来都一样

评论(12)
IT小君

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

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

2021-11-06T00:30:24   回复
IT小君

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

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

加里提出了一个很好的观点。如果您将编码原则用于抽象而不是“具体化”,那么许多模式开始看起来像是主题的变体。

2021-11-06T00:30:24   回复
IT小君

补充一下 tvanfosson 所说的,就实现而言,很多模式看起来是一样的。也就是说,您创建了一个接口,而您的代码中以前可能没有这个接口,然后创建了该接口的一堆实现。不同之处在于它们的用途和使用方式。

2021-11-06T00:30:24   回复
IT小君

首先,必须区分简单工厂和抽象工厂。第一个是一个简单的工厂,其中只有一个类充当对象创建的工厂,而在后者中,您连接到工厂接口(定义方法名称),然后调用实现此接口的不同工厂基于某些标准,应该有相同方法的不同实现。例如,我们有一个 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 模式是可操作的。实施明智,它们的结果是相同的。

2021-11-06T00:30:24   回复
IT小君

工厂(和工厂返回的工厂方法)

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

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

策略模式:

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

例子:

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

相关文章:

策略模式的真实世界示例

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

2021-11-06T00:30:25   回复
IT小君
  • 工厂(方法)模式。

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

  • 策略模式。

封装算法(步骤)以执行操作。所以你可以改变策略并使用另一种算法。

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

所以。如果你的工厂方法是固定的,你可能会像这样:

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

但是假设您的工厂需要更高级或动态的创建。您可以向工厂方法添加策略并更改它而无需重新编译,该策略可能会在运行时更改。

2021-11-06T00:30:25   回复
IT小君

扩展 Oscar 所说的内容并参考他的代码:

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

2021-11-06T00:30:25   回复
IT小君

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

2021-11-06T00:30:25   回复
IT小君

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

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

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

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

2021-11-06T00:30:26   回复
IT小君

我可能会离题,因为他的工厂实现示例是相当紧密耦合且非常封闭的,难怪您的选择是策略模式。工厂实现不应依赖于任何固定数量的特定类被实例化,例如:

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

...

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

}

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

2021-11-06T00:30:26   回复
IT小君

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

2021-11-06T00:30:26   回复
IT小君

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

2021-11-06T00:30:26   回复