初始化()vs构造函数()方法,创建对象时的正确用法
我们基本上都知道Constructor
和用户定义的Initialize()
方法之间的区别。初始化()vs构造函数()方法,创建对象时的正确用法
我的问题是关注对象创建的最佳设计实践。我们可以将所有Initialize()
代码放入Constructor()
,反之亦然(将所有预热代码移至Initialize
方法并从Constructor
调用此方法)。
目前,设计一个新类,我在constructor()
内部创建任何新的实例,并将其他预热代码移动到Initialize()
方法中。
您认为最好的交易点是什么?
我觉得是应该考虑多个方面:
一个构造函数应该在某种程度上,它是处于可用状态初始化的对象。
构造函数应该只初始化一个对象,而不是执行繁重的工作。
构造函数不应该直接或间接调用虚拟成员或外部代码。
所以在大多数情况下,不应该需要Initialize方法。
在初始化涉及的不仅仅是将对象置于可用状态的情况下(例如,需要执行繁重的工作或需要调用虚拟成员或外部对象时),那么Initialize方法是一个好主意。
最近我发现自己在思考这个问题(因此发现了这个问题),虽然我没有答案,但我想我会分享我的想法。
- 建设者的理想'应该只设置对象的状态,即:几个:
this.member = member;
在我看来,这与国际奥委会,继承,测试很好地发挥,只是味道不错。
然而繁重,有时是需要所以我一直试图做的是:
- 通行证在繁重。
这意味着抽象是初始化代码到其他类和传球,在这通常是可能的,如果繁重是不是真的你的对象的责任,这样做其实这refactors到更好的代码。
如果这是不可能的,你需要在使用前初始化你的类的状态,然后添加一个initialse方法。这确实增加了时间依赖到你的代码,但是这不一定尤其是在使用IoC容器时,坏事:
说CarEngine
需要DrivingAssistComputer
,而DrivingAssistComputer
需要做重初始化,即加载所有参数,天气条件检查,等等。另外需要注意的是,CarEngine
不直接与DrivingAssistComputer
互动,它只是需要它存在,在旁边做自己的事情。事实上,如果没有DrivingAssistComputer
在后台执行任务(在某处更改某个状态),引擎可能无法正常工作。如果我们使用IoC的则有:
// Without initialise (i.e. initialisation done in computer constructor)
public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
this.injectors = injectors;
// No need to reference computer as we dont really interact with it.
}
...
所以我们在这里的是一个构造函数的参数标记computer
为扶养但实际上没有使用它。因此,这是丑陋的,但让我们来添加一个初始化方法:
public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
this.injectors = injectors;
// This ofcourse could also be moved to CarEngine.Initialse
computer.Initialise();
}
...
还没一个有凝聚力的班,但至少我们知道,我们依赖电脑上,即使我们没有直接与它的构造之外的交互。
另一种选择ofcourse是有一个CarEngineFactory,做:
CarEngine CreateEngine(FuelInjectors injectors) {
new DrivingAssistComputer().Initialise();
return new CarEngine(injectors);
}
...
不过,我觉得工厂和IOC只是混淆矩阵,所以我会去的第二个选项。
很想听听这方面的一些想法。
编辑1: 我错过了上面的另一个选择是使用Initialise方法,但将此调用移动到IoC初始化模块。所以创建和初始化仍然有所封装。
+1'传递重负荷' - 这对我来说很有意义 – 2014-01-26 03:35:46
好吧。在过去,我还倾向于在构造函数中使用'initialize()'方法,而不是直接实例化对象,就像使用工厂模式一样。你认为这是一个相关的考虑因素吗? – Ray 2017-01-26 18:59:41