1

我们的应用程序大量使用工厂来吐出对象,但我经常想知道它们是否总是真的有必要,并且将“已知对象”的实例创建为 bean 并不是更好。争论是开发人员经常自定义这些返回对象的实现(它们以其接口类型返回),并且由于我们在技术上并不确切地“知道”我们得到了什么,所以最好使用工厂。我现在需要创建一个工厂,它需要接口、类实现,然后是工厂。我的对象不会改变——它确实是一个具有特定目的的具体对象......我不应该只是实例化一个获取和设置状态的 bean 吗?我试图避免过早的概括。

4

2 回答 2

3

工厂或依赖注入解决方案的全部目的是减少客户端和对象的运行时类型之间的耦合。确实,客户端必须知道接口和数据的来源,但现在来源可以自由地返回任何实现接口的类型。它还允许您将运行时类型的知识封装在一个地方——只有工厂或依赖注入解决方案需要知道。

这在生成运行时代理以实现声明性事务时很有帮助。从客户端的角度来看,他们正在处理接口。工厂可以为客户端生成管理事务的代理。

一旦您键入“new”,客户端就会被绑定到在运行时使用编译类型。改变它意味着改变客户。如果您的代码中有很多地方称为“新”,这可能是一个维护问题。

我什么时候称“新”?我认为在方法中实例化本地对象是合适的,当它们超出范围时将被 GC 处理。该方法创建它们,使用它们,然后它们就完成了。我不会在那里使用工厂或 DI 解决方案。

也许你应该关闭你的工厂并考虑像 Spring、Guice 或 PicoContainer 这样的依赖注入解决方案。

于 2009-09-26T14:41:24.043 回答
2

拥有工厂方法意味着——但并不总是意味着——对象没有公共的默认构造函数。这个想法是,如果有一个工厂方法(例如),你不应该绕过它并直接创建一个。

在最简单的情况下,几乎没有理由使用公共构造函数而不是返回新对象的公共静态方法,并且该对象只有私有/受保护的构造函数。

话虽如此,在某些情况下,您要么需要公共默认构造函数,要么不拥有它们非常不方便。示例包括使用 Spring 的 BeanWrapper。某些方法需要默认构造函数。使用 JavaBeans 接口需要它。没有它,反射可能会很尴尬(这是前两个原因的一部分)等等。

在这些情况下,拥有工厂可能没有什么价值,除非您的工厂返回一个接口并且该类实现了该接口。再说一次,也可以说大多数(如果不是全部)返回类型(和参数类型)应该是接口而不是类,但这是一个完全独立的参数。

拥有工厂的另一个潜在缺点是它会降低可测试性,因为工厂可能会依赖或修改某种形式的外部状态。不一定是这种情况,但是,例如,此代码:

Calendar cal = Calendar.getInstance();

对比

Calendar cal = new GregorianCalendar();

根据本地化/国际化会有不同的结果。

于 2009-09-26T15:05:04.537 回答