在该领域多年的经验之后,在我看来,工厂模式是不编写框架或库时不那么有趣和有用的模式之一。
我不是说工厂模式是不必要的。例如,W3C Document
接口充当各种XML节点(元素,属性,文本......)的工厂。 Eclipse JDT中的AST
类充当ASTNode
的工厂,如Assignment
,MethodDeclaration
等。我可以找到许多其他框架/库示例。
但大多数时候,在普通的客户端代码中,我从不觉得需要使用Factory模式。您不关心对象的来源或创建方式。您只需使用依赖注入通过其接口连接对象,然后这些对象可以以依赖于环境的方式“生成”生命(例如,new
手动进行简单的本地测试,Java EE环境中的bean容器, ...)。但绝不是像工厂那样,ArticleFactory.createArticle()
。
我意识到例如Spring可以被认为是一个bean'工厂',但是Spring bean工厂非常通用,而我正在谈论的Factory的实现应该有一个特定的接口,并且某种程度上仅限于创建预定义的“家庭”对象的成员。
我还注意到Factory,Composite和Visitor经常齐头并进,其中Factory创建了一组(域)相关的对象,访问者可以遍历这些对象。同样,框架的典型内容,而不是客户端代码。
因此,我的问题是:在框架之外是否存在使用Factory模式而不是普通接口和依赖注入的情况?如果是的话,是否有相关的访客?
答案 0 :(得分:2)
我使用Factory类(或方法)有一定的规律性。也许,它作为工厂的Golden Hammer antipattern的症状恰好是我理解的模式之一,但我找到了用途。我最近发现的一个用途是注入一个Factory来根据ASP.NET MVC控制器中的工作单元创建LINQ DataContexts。通过使用Factory,控制器中的方法可以使用Factory的方法按需创建新的DataContext。结合依赖注入,这使我能够模拟Factory(以及DataContext)和按需创建。
答案 1 :(得分:1)
正如Maxime Rouiller在这篇文章中所说,我希望更多的人会等到他们真正需要在实施工厂之前创建不同类型的对象。我敢打赌,大多数时候,需求永远不会实现,工厂也没有必要。
http://blog.decayingcode.com/post/anti-pattern-gas-factory-or-unnecessary.aspx
答案 2 :(得分:0)
工厂可以与依赖注入结合使用,其中从容器获取的对象与这些对象用于完成工作的对象之间的生命周期/生命周期存在差异。
一个例子:
假设您通过DI配置Web服务,并且此Web服务使用代理与其他Web服务进行通信。
这些代理需要经常关闭/处理,并且比Web服务短。不是使用代理注入Web服务(这会导致代理的生命周期绑定到Web服务,即在Web服务使用它时无法关闭它),而是使用IProxyFactory接口注入它。
通过这种方式,Web服务可以要求IProxyfactory接口创建一个IProxy实现,在该实现上,它可以将调用委托给其他服务。 Web服务可以在每次使用代理时关闭/处置代理。
答案 3 :(得分:0)
也许一个具体的例子会有所帮助。
在我的CAD / CAM软件中,我有一个DLL目录,每个DLL都有不同数量的参数形状。所有形状都实现了IParametricShape接口。每个DLL都有一个Factory类,它有一个返回IParametricShape集合的方法。这将添加到软件的主列表中,并可供用户使用。
CAD / CAM软件非常适合我的行业,我们如何将它用于文件类型和报告。更多类型的软件使用哪些。您有一个报告列表,每个报告都实现了一个IReport接口。你有一个工厂返回一组IReports。您添加了您的主报告列表,并使其可供用户使用。通过更改DLL和Factory类,您可以改变集合并轻松添加新报告。与您处理的文件类型相同。
最后,您可以在界面上拥有属性,以便您可以将哪个报告(或文件类型)排序到软件中的哪个位置。例如,我有一系列商店标准报告,其中包含打印出客户设置参数的报告,另一个 与客户正在处理的工作相关的报告的集合。一个属性告诉我哪个报告是哪个。或者,您可以使用两个单独的工厂方法,一个用于生成集合A,另一个用于生成集合B。