工厂方法设计模式`static`修饰符必须与否

时间:2016-05-07 11:40:54

标签: java oop design-patterns

我正在研究设计模式。我已经研究过java中的Factory Design Pattern,而且我有一些我不太了解的东西,而且我正在编写它们。

  1. Factory设计模式与Factory Method设计模式之间是否存在任何差异。
  2. 我在一些examples中看到,工厂类的get方法是static,有些examples不是static。什么是正确的方法。
  3. 任何帮助都会表示赞赏。

3 个答案:

答案 0 :(得分:1)

我没有太深入的设计模式,因为我没有在很多抽象中摄取大量书籍讨论它们,但我当然知道它们是什么,并知道如何应用它们。以下是我对这两种模式的理解:

  • Factory是一种模式,它通过处理一个知道如何构造其他对象的对象来延迟对象的实例化。这可以有几个优点。例如,假设您正在编写一个主题池库。池包含可以执行某些操作的对象,并且您希望能够创建任何大小的池。池中的每个对象必须是不同的对象。您可以要求池中的用户在池中为您提供所需数量的对象,但您也可以要求他们使用您自己实例化对象的单个工厂。这样,您还可以动态更改池的大小,破坏或重新生成对象等...它提供了您所需的所有灵活性,而无需了解池所持有的对象。

  • Factory method不同。让我们假设您有一个包含大量参数的大型构造函数。其中一些参数可能具有默认值,或者您可能有多种方式来配置此类。您当然可以为每个典型配置(参数集)添加构造函数,但由于所有构造函数共享相同的名称,因此这不是用户友好的。为了使它更容易,您可以使用静态方法,只需使用适当的配置调用构造函数。优点是您可以命名这些方法(defaultHttpClientForProddefaultHttpClientForDev等...)。另一个用例是如果你有一个庞大的类层次结构,比如一个由几十个类扩展的抽象类Car。您可以使用每个单独的构造函数来构建您的梦想汽车,但您必须查看目录的每个页面以确定您想要的那个。或者你可以有一个页面来总结所有可用的汽车,这将是一个包含许多工厂方法的类,使它们更容易被发现。

对于你的第二个问题,我会说这取决于。如果您不需要过多地定制工厂或注入大量上下文,那么使用带有某些参数的静态方法就可以解决问题。如果您希望工厂更易于配置,那么具有属性和实例方法的类将更好。

答案 1 :(得分:1)

具体到您的问题:

  1. 抽象工厂&工厂方法是两种不同的设计模式。有关详细说明,请参阅四人帮(设计模式)。关键区别是 抽象工厂或工厂 是关于创建相关对象的族(注意单词族意味着对象组),而 工厂方法 提供了一种创建方法来创建一种特定类型的对象(不是系列),可以通过多个工厂实现类来实现。从本质上讲,Factory Method用于实现Factory或Abstract Factory模式,但反之亦然。
  2. static方法而言,模式本身并不强制要求它。它特定于Java&因此,静态修饰符用于确保工厂getInstance()或任何创建方法 Singleton 。您不希望多个Factory实例,因此在Java中,您通过拥有static Factory实例来实现,因此,您需要static方法来返回static实例。

答案 2 :(得分:1)

不同的教程似乎意味着工厂设计模式的不同。我会说你链接中的那些都是简单的工厂。我认为这篇文章简单地解释了差异:Simple Factory vs. Factory Method vs. Abstract Factory

可以通过使用静态方法来识别简单工厂来创建不同的子类,通常使用某种if / else或switch结构。第二个链接中的示例实际上并不使用静态方法,但它可以很容易地变为静态而不会发生太大变化。

在Gang of Four一书中,工厂方法模式定义为:

  

定义用于创建对象的接口,但让子类决定   要实例化的类。 Factory方法允许类延迟   它用于子类的实例化。

由于使用了子类,静态方法在这里不起作用,因为它们无法被覆盖。以这种方式完成的形状示例更像是:

public interface ShapeFactory {
    Shape getShape();
}

public class CircleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Circle();
    }
}

public class RectangleFactory implements ShapeFactory {
    public Shape getShape() {
        return new Rectangle();
    }
}

ShapeFactory shapeFactory = new CircleFactory();
...
Shape shape = shapeFactory.getShape();

在这里,我们可以将工厂的创建与其使用分开。工厂可以在一个类中创建,然后传递给另一个类,因此类可以通过由另一个类配置来创建不同类型的对象。

或者在Java 8中,我们可以使用:

Supplier<Shape> shapeFactory = Circle::new;
...
Shape shape = shapeFactory.get();