我想知道在getter和setter或代码中的其他地方进行验证是否是个好主意。
在优化和加速代码方面,这可能会让您感到惊讶,我认为您不应该在getter和setter中进行验证,而应该在您更新文件或数据库的代码中进行验证。 我错了吗?
我想知道在getter和setter或代码中的其他地方进行验证是否是个好主意。
在优化和加速代码方面,这可能会让您感到惊讶,我认为您不应该在getter和setter中进行验证,而应该在您更新文件或数据库的代码中进行验证。 我错了吗?
那么,为什么类通常包含具有公共getter / setter的私有成员的原因之一正是因为它们可以验证数据。
如果你的数字可以在1到100之间,我肯定会在setter中放置一些验证它的东西,然后可能抛出一个被代码捕获的异常。 原因很简单:如果你不在setter中这样做,你必须记住每次设置时1到100的限制,这会导致重复的代码,或者当你忘记它时,它会导致无效的状态。
至于表现,我在这里与Knuth:
“我们应该忘记小的效率,比如大约97%的时间:过早的优化是所有邪恶的根源。”
@Terrapin,re:
如果你拥有的只是一堆[简单的公共集合/获取]属性......它们也可能是字段
与场相比,属性具有其他优势。 它们是一个更明确的契约,它们是序列化的,它们可以在以后调试,它们是通过继承扩展的好地方。 笨拙的语法是偶然的复杂性 - 例如.net 3.5克服了这一点。
一个常见的(也是有缺陷的)做法是从公共字段开始,然后在“根据需要”的基础上将它们转换为属性。 这违反了与消费你的班级的任何人的合同,所以最好从属性开始。
从拥有最易维护的代码的角度来看,我认为您应该在属性的setter中尽可能多地进行验证。 这样您就不会缓存或以其他方式处理无效数据。
毕竟,这就是属性的意义所在。 如果你拥有的是一堆属性,如......
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
......他们可能也是田地
这取决于。
通常,代码应该快速失败。 如果值可以由代码中的多个点设置,并且只在检索到值后验证,则错误似乎出现在执行更新的代码中。 如果setter验证输入,您就知道正在尝试设置无效值的代码。
我尝试永远不要让我的对象进入无效状态,因此setter肯定会进行验证以及任何改变状态的方法。 这样,我就不必担心我正在处理的对象是无效的。 如果将方法保持为验证边界,那么您永远不必担心验证框架和IsValid()方法调用遍布整个地方。
验证应与验证方法中的getter或setter分开捕获。 这样,如果需要在多个组件之间重用验证,则可以使用它。
当调用setter时,应该使用这样的验证服务来清理对象的输入。 这样,您就知道存储在对象中的所有信息始终有效。
您不需要对getter进行任何类型的验证,因为有关该对象的信息已被信任为有效。
在数据库更新之前不要保存验证! 最好快速失败 。
你可能想看看Eric Evans的Domain Driven Design 。 DDD有这个规范的概念:
...用于特殊目的的显式谓词式VALUE OBJECTS。 SPECIFICATION是一个谓词,用于确定对象是否满足某些条件。
我认为快速失败是一回事,另一个是保持验证逻辑的地方。 域是保持逻辑的正确位置,我认为Domain对象上的规范对象或验证方法将是一个好地方。
我喜欢实现IDataErrorInfo并将我的验证逻辑放在其Error和this [columnName]属性中。 这样,如果您想以编程方式检查是否存在错误,您只需在代码中测试这些属性中的任何一个,或者您可以将验证交给Web窗体,Windows窗体或WPF中的数据绑定。
WPF的“ValidatesOnDataError”绑定属性使这一点变得特别容易。