2012-12-19 80 views
3

你有一个不可变的对象,你可以在接受几个参数的构造函数中设置它的内部变量。在不可变的构造函数方法中验证构造函数参数是坏的还是好想法?

问题
你看到的任何问题,以验证构造函数参数不可变对象的构造方法,如果没有有效的扔ArgumentExceptions

(对我来说,这是有道理的,但我想如果要问有一些更好的方法或一些与此不正常 - 例如,如果它是一个更好的设计,从构造移动验证到工厂)

或者,如果我被改写的问题概括它:

是否确定把业务规则明智的逻辑构造方法?或者应该构造函数总是没有什么比设置对象的内部?

感谢

+3

关于术语的一点......缺省构造函数是由编译器在没有用户提供的构造函数的情况下自动生成的,并且是无参数的。 – spender

+0

谢谢,我已经删除了'default':) – pencilCake

回答

4

从某种意义上说,在构造函数本身中进行验证是有意义的,因为您知道它的所有用法都将通过该单一点,并且任何其他将使用您的代码的开发人员都将因为您的“低级”验证。

如果您将验证移动到调用链的更高位置,那么您将类代码保持清洁,但是您将代码暴露给“您正在使用它错误”的错误的可能性。

+0

也许你可以通过在类本身上使用静态工厂方法来获得最好的两种选择,并且使构造函数是私有的? – Grundlefleck

+1

是的,这将是一个符合两个愿望的解决方案。 – dutzu

2

如果是我,我会把验证参数之前,我将它们传递到构造函数。你永远不知道你的代码将如何发展,因此如果你在工厂进行验证,你应该提供更多的可见性并且感觉“更清洁”。

4

构造函数验证在无效数据的情况下有一个小问题:那么你做什么?你不得不抛出一个异常,如果你经常创建“无效”实例,这可能会很尴尬,并且性能会受到影响。

为了在每次实例化对象时摆脱try ... catch,无论如何您都必须创建工厂。

我认为工厂是一个很好的方法,但方式稍有不同 - 验证赋给工厂方法的参数,然后创建一个(有效的)实例。

0

如果您可以选择在哪里提出例外,那么只要在任何地方记住用try..catch来包围它,就可以考虑到您的代码库的其他用户。这往往不取决于课程的目的,以及你如何看待它的使用。但一致性也很重要。

有时,不要在其中引发异常,而是为不可变类型提供单独的ValidateInstance()函数。你的其他选择就像你说的类创建(通过工厂或构造函数)或者类的用法(如果错误可以被更快抛出,通常是个坏主意,但有时候是有道理的)。

将它们放在构造函数中的优点是,如果您稍后再选择它们,它们也将在Factory方法中显示。

HTH

2

类应,以最好的它的能力,记录它使担保,并尽最大努力保持自身处于有效状态,在任何时候。任何不合适的来电或将对象置于无效状态都会产生异常。

这也适用于构造函数。不验证其输入的构造函数使其他人可能创建类的无效实例。但是,如果你总是验证,那么任何提及你班级的人都可以确信它是有效的。