Initialize()vs Constructor()方法,正确用于创建对象

我们都从根本上知道Constructor和用户定义的Initialize()方法之间的区别。

我的问题集中在对象创建的最佳设计实践上。 我们可以将所有Initialize()代码放入Constructor() ,反之亦然(将所有预热代码移动到Initialize方法并从Constructor调用此方法)。

目前,在设计一个新类时,我在constructor()创建任何新实例,并将任何其他预热代码移动到Initialize()方法中。

您认为最好的权衡点是什么?

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

  • 构造函数应该以一种处于可用状态的方式初始化对象。

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

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

因此,在大多数情况下,不需要Initialize方法。

如果初始化涉及的不仅仅是将对象置于可用状态(例如,当需要执行繁重的工作或需要调用虚拟成员或外部时),那么Initialize方法是个好主意。

我最近发现自己在考虑这个问题(因此找到了这个问题),虽然我没有答案,但我认为我会分享我的想法。

  • 理论上’构造函数’应该只设置对象状态,即:一些:

this.member = member;

在我看来,这与IoC,inheritance,测试很好地相得益彰。

但有时需要举重,所以我一直想做的是:

  • 通过繁重的举重。

这意味着将初始化代码抽象到另一个类并将其传入。这通常可能是因为繁重的工作并不是您的对象责任,所以这样做实际上可以重构更好的代码。

如果这是不可能的,并且您确实需要在使用前初始化您的类的状态,那么添加一个initialse方法。 这确实会在代码中添加时间依赖性,但这不一定是坏事,特别是在使用IoC容器时:

假设CarEngine需要一个DrivingAssistComputer ,并且DrivingAssistComputer需要进行大量初始化,即加载所有参数,天气状况检查等。另外需要注意的是CarEngine不直接与DrivingAssistComputer交互,它只需要它存在,做它本身的一面。 事实上,如果没有DrivingAssistComputer在后台执行DrivingAssistComputer (在某处更改某些状态),引擎可能无法正常工作。 如果我们使用IoC,那么我们有:

 // Without initialise (ie 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标记为依赖,但实际上并未使用它。 所以这很难看,但是我们添加一个Initialise方法:

 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:我错过的另一个选项是使用Initialise方法,但将此调用移至IoC初始化模块。 因此创建和初始化仍然有些封装。