我正在学习设计模式。我学习过java中的工厂设计模式,我有一些不太理解的东西,我正在下面写。
Factory
设计模式和Factory Method
设计模式有什么不同吗- 我在一些例子中看到,Factory类的
get
方法是static
,而一些例子不是static
。什么是正确的方法
任何帮助都将不胜感激。
我对设计模式不太深入,因为我没有吸收大量抽象讨论它们的书籍,但我当然知道它们是什么,并知道如何应用它们。以下是我对这两种模式的理解:
-
Factory
是一种模式,它通过传递一个知道如何构造其他对象的对象来延迟对象的实例化。这可能有几个优点。例如,假设您正在编写一个游泳池库。池包含可以执行某些操作的对象,并且您希望能够创建任何大小的池。池中的每个对象都必须是不同的对象。您可以要求池的用户在池中提供他们想要的对象数量,但也可以要求他们提供一个单独的工厂,您将使用该工厂来自己实例化对象。通过这种方式,您还可以动态更改池的大小、销毁或重新生成对象等……它提供了您所需的所有灵活性,而无需了解池中的对象。 -
CCD_ 7不同。假设您有一个包含大量参数的大型构造函数。其中一些参数可能具有默认值,或者您可能有各种方法来配置此类。你当然可以为每个典型的配置(参数集)添加一个构造函数,但这并不方便用户,因为所有的构造函数都有相同的名称。为了更容易,您可以使用静态方法,这些方法只调用具有适当配置的构造函数。优点是你可以命名这些方法(
defaultHttpClientForProd
、defaultHttpClientForDev
等)。另一个用例是,如果你有一个庞大的类层次结构,比如说一个由几十个类扩展的抽象类Car
。你可以使用每个单独的构造函数来构建你的梦想汽车,但你必须查看目录的每一页来决定你想要哪一辆。或者,你可以有一个单独的页面来总结所有可用的汽车,这将是一个包含许多工厂方法的类,使它们更容易被发现。
关于你的第二个问题,我认为这取决于情况。如果您不需要过多地自定义工厂或注入大量上下文,那么使用一些参数的静态方法就可以了。如果您希望您的工厂更加可配置,那么一个具有属性和实例方法的类会更好。
具体针对您的问题:
- 抽象工厂&工厂方法是两种不同的设计模式。有关详细解释,请参阅"四人帮"。关键区别在于Abstract Factory或Factory是关于创建相关对象的族(注意单词族的意思是对象组),而Factory方法提供了一种创建一种特定类型对象(而非族)的创建方法,该方法可以由多个工厂实现类实现。从本质上讲,工厂方法用于实现工厂或抽象工厂模式,而不是相反
- 就
static
方法而言,它不是由模式本身强制执行的。它是特定于Java&因此,使用静态修饰符来确保Factory的getInstance()
或任何创造性方法是Singleton。您不需要Factory的多个实例,因此在Java中,您通过拥有Factory的static
实例来实现,因此,您需要static
方法来返回static
实例
不同的教程似乎意味着工厂设计模式的不同之处。我想说,你链接中的都是简单的工厂。我认为这篇文章简单地解释了区别:简单工厂与工厂方法与抽象工厂
简单的工厂可以通过使用静态方法来创建不同的子类来识别,通常使用某种if/else或switch结构。第二个链接中的示例实际上并没有使用静态方法,但可以很容易地将其设置为静态方法,而无需进行太多更改。
在"四人帮"一书中,工厂方法模式被定义为:
定义用于创建对象的接口,但由子类决定要实例化的类。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();