无法使用工厂方法模式控制实例?

时间:2011-08-13 18:44:00

标签: java design-patterns

工厂的一个好处是它不一定要返回一个新对象。它可以改为从对象池返回对象。

这很好,但为了让工厂在需要时创建一个对象,这些对象类需要公共构造函数。因此,理论上有人可以直接上课并要求新的实例,工厂也不知道。在工厂外创建的对象不会添加到对象池中。

有没有办法阻止在工厂外创建对象?

6 个答案:

答案 0 :(得分:2)

是否有令人信服的理由阻止对象在工厂以外被实例化?这种控制通常效率不高。请记住,由于反射,你永远无法完全阻止它。你只是让它更烦人。如果在项目中编码样式,性能或类似问题,最好使用静态分析工具,如checkstylePMDFindBugs来查看对象实例化在错误的地方。

答案 1 :(得分:1)

你应该让你的包裹私密到它的包

答案 2 :(得分:1)

或者,您可以使实例类成为工厂的私有嵌套类。

答案 3 :(得分:0)

他们可以拥有受保护的构造函数,而不是公共构造函数。

答案 4 :(得分:0)

您可以采取一些措施来控制对构造函数的访问:

  1. 为类提供一个包作用域(默认)构造函数,并使工厂存在于同一工厂中:如果这样做,则只有同一个包中的类才能访问该构造函数。这应该足够好了。

  2. 让你的类成为工厂的私有内部类:这样做可以确保只有工厂可以使用它们。

  3. 不要在代码中做任何事情,而是要写一些关于你认为客户应该使用工厂的原因的好文档:有时可以让人们潜入自己的脚,如果他们认为他们有一个很有理由在你想象的范围之外这样做。

答案 5 :(得分:0)

我实际上并不推荐以下内容,我可能永远不会自己做。

话虽如此,你可以做的一件事是让所有物品检查它们是否由工厂建造,如果没有,则抛出一个合适的例外。

要做到这一点,在对象的构造函数中只需调用Thread.currentThread().getStackTrace(),然后'展开'堆栈,直到你在构造函数之后(之前)到达框架。现在,您可以检查调用者并抛出异常,如果它不是Factory

此技术可以阻止新对象实例即使通过反射也可以实例化。

现在显然在检查和展开堆栈跟踪时会有开销,如果工厂无法实际/缓存以前构造的对象(即每次都必须返回一个新实例),并且你要调用它足够多次可能会变得昂贵。

因此,通常的警告“只因为它可以完成,并不意味着你应该这样做”适用。再说一次,如果你真的必须这样做,那么至少知道一种方法是很好的。