关于java:Factory和Strategy模式有什么区别?

What is the difference between Factory and Strategy patterns?

有人能解释工厂模式和战略模式之间的区别吗?

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


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

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


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

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

加里说得很有道理。如果您使用的是编码抽象而不是"具体化"的原则,那么许多模式开始看起来像主题上的变体。


除了Tvanfosson所说的,很多模式在实现方面看起来都是一样的。也就是说,很多情况下,您已经创建了一个接口,在您的代码中可能以前没有一个接口,然后创建了该接口的一系列实现。区别在于它们的用途和使用方法。


  • 工厂(方法)模式。

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

  • 战略模式。

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

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

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

1
2
3
4
5
6
7
8
 public Command getCommand( int operatingSystem ) {
      switch( operatingSystem ) {
           case UNIX    :
           case LINUX   : return new UnixCommand();
           case WINDOWS : return new WindowsCommand();
           case OSX     : return new OSXCommand();
       }
  }

但假设您的工厂需要更先进或动态的创建。您可以在工厂方法中添加一个策略并更改它,而不必重新编译,该策略可能在运行时更改。


首先,必须区分简单工厂和抽象工厂。第一个是一个简单的工厂,其中只有一个类用作对象创建的工厂,而在后者中,您连接到工厂接口(定义方法名称),然后调用实现此接口的不同工厂,这些工厂应具有基于so的同一方法的不同实现。ME标准。例如,我们有一个ButtonCreationFactory接口,由两个工厂实现,第一个是WindowsButtonCreationFactory(用Windows的外观创建按钮),第二个是LinuxButtonCreationFactory(用Linux的外观创建按钮)。所以这两个工厂都有相同的创建方法和不同的实现(算法)。您可以在运行时基于所需的按钮类型的方法来引用它。

例如,如果您希望按钮具有Linux外观:

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

或者如果你想要Windows按钮

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

正是在这种情况下,它产生了一种策略模式,因为它区分了用于创建的算法。但是,它在语义上不同于它,因为它用于对象创建,而不是操作算法。所以,基本上,对于抽象工厂,您可以使用不同的策略来创建对象,这使得它非常类似于策略模式。然而,抽象工厂是创造性的,而战略模式是可操作的。在实现方面,它们的结果是相同的。


工厂(和工厂返回的FactoryMethod):

  • 创建型模式
  • 基于继承
  • 工厂返回工厂方法(接口),该方法反过来返回具体对象
  • 您可以为接口替换新的具体对象,客户机(调用者)不应该知道所有具体实现。
  • 客户端始终只访问接口,并且可以在工厂方法中隐藏对象创建详细信息
  • 看看这篇维基百科文章和javarevisited文章

    战略模式:

  • 这是一种行为模式
  • 这是基于授权
  • 它通过修改方法行为来改变对象的胆量
  • 它用于在算法家族之间切换
  • 它在运行时更改对象的行为
  • 例子:

    您可以为特定项目(机票或购物车项目)配置折扣策略。在本例中,您将在7月至12月期间为一个项目提供25%的折扣,在1月至6月期间不为该项目提供折扣。

    相关职位:

    战略模式的现实例子

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


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


    为了扩展奥斯卡所说的话和他的代码:

    getcommand是工厂,unixcommand、windowscommand和osxcommand类是策略


    您不能仅仅通过查看代码或分类来理解差异。要正确掌握采空区模式,请寻找其意图:

    策略:"定义一系列算法,封装每个算法,并使它们可互换。策略允许算法独立于使用它的客户机。"

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

    这里详细解释了这两种模式的意图和区别:工厂方法和策略设计模式的区别


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


    我可能会和奥斯卡脱节,他在工厂实现方面的例子是紧密耦合的,非常封闭的,难怪你选择的是策略模式。工厂实现不应依赖于被实例化的特定类的任何固定数量,例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public Command getCommand( int operatingSystem ) {        
       return commandTable.get(operatingSystem);
    }

    ...

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

    }

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


    工厂模式是一种创建模式,使用指定的属性(行为)创建。而在创建后的运行时,u cn不会更改其属性(行为)。因此,如果你需要不同的属性(行为),你必须删除对象并创建新的具有所需属性(行为)的对象。这不是古德。而对于策略模式,U可以在运行时更改属性(行为)。