Initialize()方法与Constructor()方法,对象创建时的适当使用

35
我们都知道构造函数和自定义的Initialize()方法在本质上的区别。
我的问题关注对象创建的最佳设计实践。我们可以将所有Initialize()代码放入Constructor()中,反之亦然(将所有启动代码移动到Initialize方法中,并从Constructor中调用此方法)。
目前,在设计一个新类时,我会在constructor()中创建任何新实例,并将其他任何启动代码移动到Initialize()方法中。
在您的意见中,什么是最好的权衡点?
2个回答

33

我认为应该考虑多个方面:

  • 构造函数应该以可用的状态初始化对象。

  • 构造函数只应该初始化对象,而不是执行繁重的工作。

  • 构造函数不应该直接或间接调用虚拟成员或外部代码。

所以在大多数情况下不需要Initialize方法。

在初始化涉及更多操作时(例如需要执行繁重的工作或需要调用虚拟成员或外部代码),则最好使用Initialize方法。


1
说得好。过去我也倾向于在不直接实例化对象时使用initialize()方法而不是构造函数,比如使用工厂模式。您认为这是一个相关的考虑吗? - Ray

4

最近我一直在思考这个问题(因此找到了这个问题),虽然我没有答案,但我想分享一下我的想法。

  • 构造函数“理想情况下”应该只设置对象状态,例如:

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);
}

...

然而,我发现工厂和IoC只会让矩阵更加混乱,因此我会选择第二个选项。很想听听你们的想法。
编辑1: 我错过了另一个选项,即拥有Initialize方法,但将其调用移动到IoC初始化模块中。因此,创建和初始化仍然有所封装。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接