构造函数执行后的Init字段

时间:2012-04-10 11:00:12

标签: java oop parameter-passing

假设Car Validator和许多方法读取其属性以使其有效。 因此,构建它的最佳方法是使Car成为实例字段。

制作它的两种方法:

1)让构造函数将Car作为参数,然后调用validate()。

2)删除所有构造函数,而是将Car传递给validate方法作为参数:validate(Car car)。

如果我们想象这个验证器必须不断验证,那么就说500辆汽车。

使用 1)方法,必须实现500个验证器对象...即使垃圾收集器正在很好地完成其工作,它似乎也不是最佳实践。 好处是Car field的初始化是由constructor =>进行的。更自然的方式。

使用 2)方法,我们避免了 1)的缺点,但我们必须将init字段引入方法validate,这意味着在构造对象之后。那被认为是一种好习惯吗?实际上,只有验证方法使用Car字段,而且,只有验证方法不是私有的。

当然,还有第三种方法可以避免所有的疑惑=>将验证方法中的汽车传递给每个私人方法......但我发现这非常难看......

我应该选择哪三种方法?

3 个答案:

答案 0 :(得分:1)

我认为第二种方法是反模式,应该避免,它类似于臭名昭着的SimpleDateFormat类(它看起来像无状态和线程安全,但它不是)。

关于其他方法,如果你真的有很多私人方法,最好使用第一种方法,否则你可以使用第三种方法,它对我来说看起来不太难看。

另请注意,使用第一种方法"按原样#34;涉及比第三个更多的耦合。在第三种情况下,您可以通过注入预配置的验证器实例来将验证器的客户端与其实现分离,而在第一种情况下,您需要引入工厂以实现相同的效果。

答案 1 :(得分:1)

良好做法通常可以避免弊端。

使用第二种方法。如果您要创建一个CarValidator类并在其上调用validate(car)来检查对象的有效性,那么这似乎是一种非常有效的方法。我不明白你为什么认为这不是最好的做法?

您是否担心在整个验证过程中设置私有Car变量并引用它,而不是通过所有私有方法传递实例?只要validate方法同步,这种方法就不会成为问题。

答案 2 :(得分:1)

我会使用第四种方法并通过将Validator对象注入Car构造函数来尽早检查汽车的有效性。我发现这个缺点远小于无效的汽车实例,并且必须在多个地方检查有效性(通过Validator对象中的validity()或者通过Validator对象中的属性)(即没有快速失败)。


更新:如果您在构建期间无法验证Car实例,例如因为您在客户端,我会将Car实例视为服务器端的污点值,并使用the tainting checker和您的方法2来解释它们。