假设我有一个名为“Controller”的接口。有几个类实现了这个接口,我不知道这些类(例如,类名位于xml文件中)。现在,要使这个Controller实现类工作,他们必须获得对其他对象(可能是数据对象)的一些引用。这是我的问题,即初始化这些对象(控制器对象)的最佳方法是什么?
我想到了几个解决方案,但我不确定这里最好的方法是什么。
第一次:从类名实例化对象时,我可以搜索“特殊”构造函数(通过反射),该构造函数具有Controller对象所需的对象引用。但是从我在其他问题中读到的内容来看,这不太可能是一个好的解决方案,因为我会强制在类中存在一个特殊的构造函数。有时我会读到一般的反思是邪恶的,最好避免。
第二次:我向Controller接口添加了一个特殊的init(a,b,c)方法,该接口需要在创建对象后直接调用。这将强制一系列调用(第一个init(..),然后休息)到对象使其工作,这可能也很糟糕。顺便说一下,init() - 接口中的方法根本就是坏事吗?
第三次:在阅读this评论之后我想到了以下内容:我没有实现Controller接口的类的类名(在xml文件中)我有类属于具体Controller类的工厂名称。并且这个工厂将使用方法createController(a,b,c)实现一个接口,然后工厂将知道它将实例化哪个类以及调用哪个构造函数来承载其他引用(如数据对象)。这样做的缺点就是实例化Controller类的附加类,一般来说可能只是一点开销。
您认为最好的方法是什么?或者你能想到其他可能比这三种方式更好的东西吗?
谢谢!
答案 0 :(得分:4)
在你提到的方法中,我会选择第二种(基于工厂的方法)。但是,由于你正在做的 是一种依赖注入形式,所以也要考虑Guice,http://code.google.com/p/google-guice/ - 它可以让你自动完成大部分工作。
答案 1 :(得分:2)
你要做的事情与Spring的做法非常相似。 在xml文件中,控制器节点将具有子节点以指定要设置的属性。 通过调用默认构造函数来实例化您的控制器。然后使用反射设置属性。
答案 2 :(得分:0)
在其他语言类似的东西中,我已经知道使用init()解决方案。
答案 3 :(得分:0)
另一种选择可能是使用Unsafe.allocateInstance(Class)来创建实例而不调用构造函数。您可以使用反射设置字段。
这假设您的构造函数没有任何副作用。