我想知道,在实际意义上,在大规模(Java - 我的案例)项目中,最好只是编写防御逻辑来防止数据库中的无效数据,或者只是花时间来完成确保您不接受任何无效数据?请记住,这里的问题是有很多情况下null是可以的,并且在很多情况下null不是,所以确保没有无效数据的情况是非常重要的。
我问的原因是因为我正在处理一个大型项目并且发现自己正在追逐一些令人讨厌的空指针异常,只是为了意识到它被抛出的原因是因为没有设置大型对象的某些模糊属性。所以,我和系统工程师谈谈只是为了意识到在设计中,应该由用户设置,等等。
注意:请不要将这些问题归结为“糟糕的系统设计”。设计是否可以更好不是手头的问题(显然任何设计都可以改进)。 我想把这个表格作为开发人员的观点,这个开发人员已经加入了一个非常先进的项目(在花费的时间和代码行数方面)以及从这一点开始他应该做些什么?
谢谢!
**我刚刚想到很多人可能会认为这是一个自以为是的问题?如果是这种情况,那么任何人都可以随意将其作为社区维基。我不确定。可能会有一些惯例或“良好实践”,许多人遵循我不知道的,随后根本不会是一个固执的问题,只是告诉我,一个新的开发人员,这个实践。
答案 0 :(得分:4)
我倾向于编写我的对象以在构造时进行验证(大多数我的对象是不可变的)。 Setters也将验证。
验证包括空检查(最常见 - 我尝试非常难以防止空值,并在允许空值时注释代码),对值进行一些健全性检查。这些将导致IllegalArgumentExceptions
失败(通常)
我何时执行这些验证?不在每个对象/辅助对象等上。通常在我的应用程序中的适当层或组件集之间进行某种转换。一个好的经验法则是,任何可能被新客户端重用的组件都将执行验证。因此(在您的示例中)数据库层将提供验证,通常独立于其他层(如果您认为应用程序的不同层以不同形式表示数据,则这不是不合理的)
验证级别取决于该数据的来源。例如最严格地对用户输入执行验证(例如,文本字段中的条目等)。我不太严格地检查来自(例如)Spring XML配置的输入。
验证非常重要。您正在检查的数据,而不是在它会导致问题时。这样可以让生活变得更轻松(想象一下,如果你接受错误的输入,序列化对象,一年后反序列化,发现你不能使用它!)
答案 1 :(得分:1)
使用数据库约束(例如,NOT NULL)以任何方式禁止数据库中的无效数据,并在Java应用程序代码中禁止输入验证以禁止用户访问输入无效数据。
单独的数据库约束是不够的,因为用户应该看到有意义的验证错误消息。仅输入验证是不够的,因为即使输入验证代码中存在错误,数据库中的数据也必须处于有效状态。此外,数据库中的数据不一定必须来自您的应用程序。
答案 2 :(得分:0)
如果用户应该输入稍后将检查其有效性的数据,则在用户完成必填字段之前,您不应接受任何数据。接受不完整的数据并将不完整的数据写入数据库是没有意义的。
但是,在尝试使用数据或将其传回给用户之前,还需要在从数据库中检索数据时检查数据。也许数据已经从一些外部来源发生了变化,也许数据只是腐败,但你需要对它进行验证。
所以真正的答案是“两次”。你需要在两端检查它。