java中的工厂模式

java中的工厂模式,java,design-patterns,factory-pattern,Java,Design Patterns,Factory Pattern,我使用的java代码应该使用工厂模式,但我并不完全相信这种模式 我的代码执行以下操作: // the factory class SomeFactoryImpl { Set<SomeClass> getSomeListOfObjects(); } //工厂 类SomeFactoryImpl{ 设置getSomeListOfObjects(); } 在代码的某个地方: { ... SomeFactory factory = new SomeFactoryImpl();

我使用的java代码应该使用工厂模式,但我并不完全相信这种模式

我的代码执行以下操作:

// the factory
class SomeFactoryImpl {
   Set<SomeClass> getSomeListOfObjects();
}
//工厂
类SomeFactoryImpl{
设置getSomeListOfObjects();
}
在代码的某个地方:

{ ...
    SomeFactory factory = new SomeFactoryImpl();
    Set<SomeClass> list = factory.getSomeListOfObjects();
}
{。。。
SomeFactory=新的SomeFactoryImpl();
Set list=factory.getSomeListOfObjects();
}
我考虑的问题是,如果工厂类没有静态create()方法,那么就需要实例化工厂,这应该和实例化对象本身一样复杂

我不认为这样的工厂可以返回要生产的对象的集合是足够好的。我觉得如果在实际从工厂创建对象之前需要创建工厂实例,可以有更干净的解决方法

我觉得如果create方法是factory类的静态方法会更好。但我也确信我的观点并不完全“正确”

因此,So社区能否举例说明实例化工厂对象比使用静态创建方法更好


此外,我还遇到了一个类似问题的答案,其中列出了这些链接和答案:因此我需要清楚地了解它们之间的区别,以及与代码示例之间的区别。

我想,创建对象的静态方法是最流行的方法,但也有一些用例首先创建工厂实例是有意义的。例如,如果您想将它与一个注册表组合(其中应允许多个注册表共存)


此外,如果工厂依赖于某些动态上下文信息(数据库连接,…),我认为最好让工厂实例来处理这个问题。

首先,您忘记了工厂模式的主要目的,我打开了《四人帮》一书,书中说:

定义用于创建objet的接口,但让子类决定实例化哪个类。Factory方法允许类将实例化推迟到子类

这意味着您实际上定义了一个接口,因此
somefactorympl
应该实际实现在其他地方定义的接口。当您有许多需要实例化的对象,但不想关心它们是哪种类型的对象时,这就很方便了。。例如,我使用它们开发了一个远程swing应用程序,其中客户端通过序列化下载了客户端VM中不存在的某些类的定义。每个类都定义了一个JPanel的子类,该子类包含其特定的视图,但当到达客户端时,我必须找到一种方法来在不知道这些类的情况下对它们进行初始化,因此我使用工厂模式调用工厂类,并让它实例化我的uknown对象(尽管它扩展了我定义的JPanel的子类)。 另一个例子是生成特定于案例的对象以满足您的需要。例如(就像wikipedia页面中与此设计模式相关的内容)您可以认为一个工厂构建了对象,然后为同一类型的对象创建了另一个工厂,但用于生成“假对象”,这将导致某种单元测试失败

但是,您也可以使用静态方法解决您的特定问题,但请考虑将生成项的部分与在大型项目中使用它们的部分分开。当然,开发客户机部件的人应该只知道使用哪个工厂接口,并且只知道使用其他部件中定义的所有对象


创建模式是一种“设施”模式,用于定义构造函数的自定义版本,而不用担心使用标准定义(方法的名称等于类的名称),但它并没有什么特别之处。只是用另一种方式来表示对象。。创建模式实际上无法解决任何类型的特定问题(不包括具有相同数量和类型参数的构造函数)。

以下是我创建factory对象实例的原因

  • 它允许我创建一个工厂,配置它(创建蓝色小部件和红色小部件等等),然后让它可以根据需要创建我的蓝色小部件和红色小部件。请注意,这不同于使用
    RedWidgetFactory
    BlueWidgetFactory
    。配置与所创建对象的类型正交
  • 它减少了在整个系统中使用一个工厂(通过静态方法访问)时可能遇到的线程问题。这可能有点防御性,但我发现这是一种良好的心态(特别是在大型系统中)。当然,这取决于对象的创建方式(例如,工厂是否创建共享的基础组件)
  • 依我看,你的代码确实是GoF模式的一个适当样本,即使它的使用不是完全最优的。如果我没记错的话,GoF书描述了工厂(SomeFactory,SomeFactoryImpl)和产品(SomeClass)之间的关系,但没有说明实例化工厂的细节

    如果您拥有的是一个不会被广泛使用的内部API,那么您拥有的可能就足够了。否则,您可以:

  • 让另一个类(可以说是“factory manager”)根据参数(例如JDBC中的DriverManager)或其他上下文信息选择工厂实现
  • 使用某种依赖注入框架
  • 如果使用#1,我个人通常会尝试用JDBC建模,其中:

    • Driver
      将是抽象工厂
    • 连接
      语句
      等都是产品
    • DriverManager
      (未在GoF手册中明确指定)是一个实用程序类,它根据传入的JDBC URL为您选择工厂
    (在本例中,如果您使用
    getConnection(…)
    m,则
    DriverManager
    会继续为您创建产品
    new OracleDriver().connect(...)
    
    { ...
        SomeFactory factory = new SomeFactoryImpl();
        Set<SomeClass> list = factory.getSomeListOfObjects();
    }
    
    public ThisClass(SomeFactory someFactory) {
        this.factory = someFactory;
    }   
    
    { ...
        Set<SomeClass> list = factory.getSomeListOfObjects();
    }