类应该验证自己还是创建另一个类来验证它?

时间:2010-02-08 17:36:17

标签: oop

假设我有一个类:

class NavigationData
{
  float roll;
  float pitch;
  double latitude;
  double longitude;
}

如果我想创建一个方法:

const bool validate() const;

基本上验证4个字段是否包含有效值。

validate()应该是NavigationData类的一部分,还是应该创建一个类似于NavigationDataValidator的东西,它包含一个validate(const NavigationData&)方法。

我只是举一个简单的例子,显然我的真正的课程比这复杂得多。我正在寻找好的OO原则。

换句话说:给定一个方法,我们如何知道它是否属于该类,或者应该属于一个单独的类?

8 个答案:

答案 0 :(得分:21)

通常,一个类自己有责任确保它保持逻辑上一致且有效的内部状态。例如,Person可能有一个构造函数,如果没有这些数据,Person上的操作毫无意义,则需要使用名字和姓氏。

然而,“逻辑一致且有效”“在域中有意义”不同,所以有时候外部类的责任是确保遵守域规则。例如,PersonValidator可能要求Person拥有位于美国的电话号码。但是Person不一定需要了解PhoneNumber是否在美国。

一个好的经验法则是,除了已经属于该类的数据之外,如果需要该类外部的州或域规则,您还需要考虑进行外部验证。如果类的实例的状态可能来自多个源(例如,数据库,Web表单,文件等),您可能还希望将验证集中在外部类中。

答案 1 :(得分:7)

正确的答案是:取决于

放置这种对象逻辑的自然之处在于对象本身。有时虽然验证规则可能依赖于规则引擎或某种更大的“框架”来验证内容。您不希望在对象内部进行验证的另一种情况是验证属于另一层,层或应用程序(例如视图层)。

答案 2 :(得分:3)

你的类应该以这样的方式设计并提供这样的方法,使validate()始终为真

  • 在调用任何公共构造函数之后
  • 在调用任何公共方法之前和之后
  • (在C ++ - land中)在调用析构函数之前

此类validate()方法称为类不变量,是Design by Contract的重要组成部分。

答案 3 :(得分:1)

我想说这取决于。如果类的数据可以单独验证,我会将该方法放在类中,但如果验证需要上下文,那么我将基于某个接口创建验证器类。

答案 4 :(得分:1)

...取决于

有时验证不是类本身的一部分,但是业务逻辑,并将其添加到类中会阻止重用,因此,验证类的使用是好的。否则,该类应该能够验证自己。

答案 5 :(得分:1)

我想说只要有效值不依赖于其他类使用NavigationData就可以验证它自己。

基本上,只要纬度和音高必须始终在+/- 90度之间,并且经度和滚动总是在+/- 180度之间,请将验证器保留在班级中。

(顺便说一句,标题怎么样?)

答案 6 :(得分:1)

这取决于具体情况。有时,您的对象在内部绝对有效,但在上下文中,其值是不可接受的。

如果你有简单的数据传输对象,那么它可能不应该验证自己。

如果您有一类Domain Model,那么它应该进行一些验证。

P.S。只是我的个人偏好:当方法返回布尔值时,isValid()而不是validate()。

答案 7 :(得分:0)

正如已经说过的,这取决于。

但在你的情况下,我会寻求一个不同的解决方案,为地理坐标创建新的不可变类

class GeoCoordinates
{
    double Latitude;
    double Longitude;
}

让本课程验证纬度和经度是否在有效限制范围内。例如,您可能还需要其他地方。

class Airport
{
    GeoCoordinates Location;
    ...
}