假设我有一个多边形类。它唯一的私有(private)数据是点数组。是否应该假设数组至少有 3 个点来编写类,并且程序的 GUI 或输入部分确保有三个点?或者成员函数应该测试数据有效性并在需要时返回错误消息?
最佳答案
其他答案中有一些很好的观点。我将尝试在这里陈述它们:
- 最终,模型有责任了解其是否处于有效状态。
- UI 需要知道模型是否处于有效状态。
- 用户界面可以保护模型免受无效状态的影响,并通过验证输入提供良好的用户反馈。
存在一些挑战:
- 如果模型和 UI 都具有验证代码,则结果要么是模型/UI 中出现重复的代码,要么是模型和 UI 的验证职责之间存在分歧。
- UI 验证变得困惑,因为某些数据字段依赖于其他字段。想象一个收集邮政编码和州(对于美国邮政地址)的应用程序。如果更改状态,您是否希望 UI 立即弹出一个对话框,显示“无效的邮政编码”?不,那会很烦人。 UI 应让用户有机会将模型置于有效状态。
- 抛出异常来捕获验证错误是一种严厉的做法。通常,您会想要一些不那么引人注目的东西。
这是我喜欢对复杂验证执行的操作:
- 允许用户输入无效值。
- 创建一个名为
ValidationError
的类,其中包含单个验证错误的人类可读的描述。 - 提供
getValidationErrors()
和isValid()
等模型方法。 - 在对模型进行任何更改之前,请让 UI 调用
isValid()
和getValidationErrors()
。如果存在任何验证错误,请让 UI 将错误显示给用户。在错误得到修复之前阻止用户继续操作。
这种方法的优点是:
- 更多的验证控制。您可以决定验证的时间和内容。
- 将验证逻辑集中在模型中。 UI 只负责获取和显示模型生成的错误。
- 如果模型在调用保存/提交方法之前调用 isValid()
,则其他代码对模型进行无效更改的风险会降低。
-没有异常处理程序。
考虑创建一个 ValidationRule
类。每个规则都包含用于验证某些内容的代码,并在无效时生成错误消息。 ValidationRule
类有一个方法 validate(aModel)
。如果您的编程语言支持闭包或一流函数,那么这尤其容易做到。
这导致每个模型类都可以拥有一个在调用 isValid()
或 getValiationErrors()
时引用的 ValidationRule
对象的动态集合。或者,使用访问者模式,使模型与验证完全解耦。这就是我在验证框架中所做的。
在模型不在客户端上的分布式应用程序中,在将更改发送到服务器之前进行一些基本验证通常是明智的做法。客户端和服务器之间的往返时间可能相当长,并且您不希望向服务器发送明显无效的请求。
最后,一个对象的有效性有时取决于不同对象中的数据!在这些情况下,我让验证规则接受多个对象,并使用 Controller 对象(或者我创建一个上下文对象)在不太精细的级别上管理验证。
关于OOP:有效数据应该在类中还是前端中处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21555907/