应该在构造函数中完成多少工作

时间:2011-09-04 20:53:48

标签: java

这是一个理论问题,我猜我正在使用它来找到标准程序。

如果我有一个构造函数方法来执行大量的设置操作来收集数据等,我应该在构造函数中保留“所有构造”,还是应该尝试从构造函数内部调用其他方法(对于代码看起来基本上),或者我应该只是初始化我必须做的所有事情,如果实际需要它们,还要留待其他事情处理?

这是一个例子。

我正在创建一个基本上是集合管理器的对象。它需要从文件中读取数据并将其存储在数组中。

我是否使用构造函数来创建具有基本属性的对象并稍后读取数据, 或者我应该读入所有信息并在构造函数中设置数组,这样可以节省时间,但在这里需要额外的时间,或者我应该按照

的方式做些什么。
 public myConstructor(String filename) {
data = readDataIn(filename);
} 

这不是实际的代码,只是一个外包到不同方法的例子来“代码”而不是超长的构造函数方法我可以说5-6个简短且外观漂亮的方法只能通过构造

3 个答案:

答案 0 :(得分:8)

构造函数应该做足够的工作以使实例进入满足其合同的状态。然后,每个方法应该做足够的工作来完成方法的合同,并使实例处于满足其合同的状态。

构造函数调用很少会导致副作用或修改其输入。这些通常不是满足合同所必需的。例如,连接类不应在构造时触及网络。由于它必须是可关闭的,因此关闭状态必须是其合同的一部分,因此“恰当的工作”标准规定构造函数将其置于准备好但尚未打开的状态。

您的特定示例将您的类与文件系统相关联。通过使用Guava Files进行读取并使用内容字符串代替,您可能会获得更可测试的更通用的类。通过编写static MyClass fromFile(String path)的方便new MyClass工厂函数,您可以方便地使用耦合到文件系统的构造函数。这会将代码中与文件系统耦合的部分移动到与实例变量交互的部分之外,从而减少要测试的可能交互的数量。正如其他人所说,依赖注入是实现解耦的另一种好方法。

答案 1 :(得分:2)

真的取决于你的API风格。请注意,您可能希望拥有多个构造函数,例如:

public MyThing(String filename) { }
public MyThing(FileInputStream filestream) {}
public MyThing(File file) { }
public MyThing(byte[] rawdata) { }

明智地将文件加载操作合并到一个或两个方法中(文件打开和文件解析)

答案 2 :(得分:0)

在这种情况下,我会使用依赖注入,因此构造函数需要已经计算过的数据,并将计算推迟到调用构造函数的任何内容。我可能会提供一个额外的静态工厂函数来完成所有这些复杂的设置,以便构造这个对象很方便(例如在测试中),但至少这个类的用户可以想出更聪明的(可能是并行化或懒惰初始化的方式来创建这个类。