我的问题关注对象创建的最佳设计实践。我们可以将所有Initialize()代码放入Constructor()中,反之亦然(将所有启动代码移动到Initialize方法中,并从Constructor中调用此方法)。
目前,在设计一个新类时,我会在constructor()中创建任何新实例,并将其他任何启动代码移动到Initialize()方法中。
在您的意见中,什么是最好的权衡点?
我认为应该考虑多个方面:
构造函数应该以可用的状态初始化对象。
构造函数只应该初始化对象,而不是执行繁重的工作。
构造函数不应该直接或间接调用虚拟成员或外部代码。
所以在大多数情况下不需要Initialize方法。
在初始化涉及更多操作时(例如需要执行繁重的工作或需要调用虚拟成员或外部代码),则最好使用Initialize方法。
最近我一直在思考这个问题(因此找到了这个问题),虽然我没有答案,但我想分享一下我的想法。
this.member = member;
在我看来,这与IoC、继承、测试很好地配合,并且很有意义。
然而,有时需要进行大量的工作,所以我一直在尝试:
这意味着将初始化代码抽象到另一个类中并将其传递进去。如果繁重的工作实际上不是你的对象责任,那么通常情况下可以这样做,这实际上会重构成更好的代码。
如果不可能这样做,并且您确实需要在使用类之前初始化其状态,则添加一个initialize方法。这确实会向您的代码添加时间依赖性,但这并不一定是一件坏事,特别是在使用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
为依赖项,但实际上并没有使用它。所以这很丑陋,但让我们添加一个Initialize方法:public CarEngine(FuelInjectors injectors, DrivingAssistComputer computer) {
this.injectors = injectors;
// This ofcourse could also be moved to CarEngine.Initialse
computer.Initialise();
}
...
虽然我们还没有形成一个凝聚力强的类,但至少我们知道尽管我们在构造函数之外没有直接与计算机进行交互,但我们仍然依赖于计算机。
当然,另一种选择是拥有一个CarEngineFactory,它可以执行以下操作:
CarEngine CreateEngine(FuelInjectors injectors) {
new DrivingAssistComputer().Initialise();
return new CarEngine(injectors);
}
...
initialize()
方法而不是构造函数,比如使用工厂模式。您认为这是一个相关的考虑吗? - Ray