关于工厂模式的问题

8
很多人说他们在项目中使用工厂模式。但是当我实际看到他们的实现时,与我在《Head First》书籍中阅读的定义完全不同。在书中,他们描述了两种工厂模式,即:
- 工厂方法:一个类指定其子类来指定基于某些参数创建哪些对象。因此,我们期望在基类中有一些抽象方法,由子类实现,目的是创建一些对象。 - 抽象工厂:提供一个工厂(以接口或抽象工厂的形式)来创建相关联或依赖的对象系列,而不指定它们的具体类。
我这里有一个问题,就是“相关或依赖对象系列”是什么意思。让我们参考http://www.apwebco.com/gofpatterns/creational/AbstractFactory.html。据我理解,这意味着在该链接中的FinancialToolsFactory能够创建TaxProcessor,它是产品系列,其实际具体产品是CanadaTaxProcessorEuropeTaxProcessor。因此,在这里,我们将拥有n个具体工厂(在这种情况下为CanadaFinancialToolsFactoryEuropeFinancialToolsFactory),它们将扩展/实现此抽象工厂,即FinancialToolsFactory
如果以上理解是正确的,那么请告诉我,因为我认为这是工厂模式的精髓。
第二个问题:
人们在工厂模式的名义下所做的是:
public class MyFactory
{
    public static <T> T getObject(Class<T> cls)
    {
        if (cls == null)
        {
            throw new IllegalArgumentException("Invalid className");
        }

        T daoObject = (T)map.get(cls);

        if (daoObject == null)
        {
            daoObject = loadObject(cls);
        }

        return daoObject;
    }
}

他们只是从主方法传递类,例如Example.class,并获取该特定类的对象实例。 现在,如果我们按照工厂模式的实际概念来看,这并不遵循头部第一本书和其他网站描述的任何两种工厂模式。对我来说,它看起来像一个实用程序类,在那里我们传递类并获取对象实例。请告诉我你们是否同意这一点?

Javadoc文档是否说明这是经典工厂模式的实现,就像那些书中所解释的那样? - Swaranga Sarma
我完全同意第二个问题。那是一个“懒加载注册表”,而不是一个“工厂”。 - Lukas Eder
2个回答

8

您对工厂方法和抽象工厂模式的理解是正确的。

当人们创建仅负责创建其他对象的类时,他们自然倾向于将它们命名为工厂。这本身并不是不合理的。问题在于没有工厂模式

这里有两个原因导致混淆:

  • 一些开发人员只想添加另一个模式,并声称他们正在使用“工厂模式”,指的是创建其他对象的对象

  • 学习设计模式的开发人员看到一个类被称为工厂,无论是否实现了模式,都会认为它必须是工厂方法或抽象工厂。这很令人困惑,因为你随后需要弄清楚它是哪一个,这就对你对真正模式的理解产生了质疑。

请记住,设计模式不仅是常见问题的解决方案,而且还用于建立讨论设计的语言。在这种情况下,您期望的设计语言与开发人员实际使用的不同。如果他们说他们正在使用特定的设计模式,则他们所做的只有错误。


感谢derekerdmann。如果您能表达一下对问题的看法,即他们所说的依赖或相关对象族是什么意思,那就太好了,或者您是否同意我关于依赖或相关对象族的说法? - M Sach
那么,假设我有一个类,其中包含一个方法,该方法接受一个字符串和一些参数,并返回由该字符串给出的类的实例以及传递给构造函数的参数,这是否可以通过反射归类为工厂模式? - Per Alexandersson
1
@Paxinum - 不行,因为没有工厂模式。你可以称你的类为工厂,这是可以的,但从设计模式的角度来看,你既没有实现工厂方法也没有实现抽象工厂。将其称为“工厂模式”的使用是错误的,因为根本不存在工厂模式 - derekerdmann

2
“家族依赖或相关对象”的意思是什么?
使用《设计模式》(Gang of Four)中的一个例子:
- 抽象工厂(`WidgetFactory`) - 具体工厂(`MotifWidgetFactory`,`PMWidgetFactory`) - 抽象产品(`Window`,`ScrollBar`) - 具体产品(`MotifWindow`,`MotifScrollBar`,`PMWindow`,`PMScrollBar`)
其中,`WidgetFactory` 是一个抽象类,`MotifWidgetFactory` 和 `PMWidgetFactory` 是它的两个具体实现类。
让我们从 MotifWidgetFactory 开始。它将生产一系列扩展或实现抽象产品的具体产品。由于它们都是由同一个工厂构建的,它们彼此兼容。你无法让 PMScrollBarMotifWindow 协同工作。
引用块中说到人们在工厂模式的名称下所做的事情如下...它看起来像是一个实用类,我们传递类并获得对象实例。
你的示例是一个工厂,因为它生成一个对象。在这种情况下,从Map中检索单例。它不遵循“工厂方法”或“抽象工厂”的模式,因此仅仅是一个以名称命名的工厂。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接