一般的数据类都应该有自己的数据合法性检查,如一个Person类,它的年龄属性是int型的,但是如果给它赋值10000则为不合法,一个人不可能活那么长时间。因此需要在创建该类的对象时必需对其进行合法性检查,若构造方法传入的是非法数据,则不让其创建该对象,并抛出异常。也许大多数人认为只需要对构造方法传入的参数进行合法性检查即可。如下所示:
class ValidClass
{
int dataValid1;
String dataValid2;
public ValidClass(int i, String str)
{
check(int i, String str);
dataValid1 = i;
dataValid2 = str;
}
void check(int i, String str)
{
if(i >100 && i <= 0) throws new RuntimeException("message");
if(str == "str") throws new RuntimeException("message");
}
void setDataValid1(int dataValid1)
{
this.dataValid1 = dataValid1;
}
}
实际上这种合法性并不可靠,这样只是保证了在构造方法中传入的数据是合法的,但是不能保证程序员在使用该对象时能传入合法的数据。如下程序代码:
ValidClass validClass = new ValidClass(2, "123");
validClass.set(200);
这样使用的话,程序运行并不会报错,但是实际上我们已经传入了非法数据到该对象中去了,因此为了避免出现程序员在使用的时候也犯这种错误,对数据的合法性检查的正确方式应如下所示:
class ValidClass
{
int dataValid;
protected checkDataValid()
{
check if dataValid valid
if (fail)
{ throws new RZXDataException(this, “.needValidate=”
+needValidate); }
}
public ValidClass(int in)
{
setDataValid(in);
}
public setDataValid(int in)
{
checkNeedValidate();
dataValid = in;
}
}
在set方法中进行合法性检查,然后在构造方法中也调用set方法设置字段值,而不直接使用类中的字段。这样做的好处很明显:不仅保证了构造方法中传入的数据必须合法,而且可以保证程序在使用的过程中不能使用非法数据,如果程序员使用了非法数据,程序运行必然出错,并且能够很快的找到错误的根源所在。
另外,有些程序员认为,有些数据类的对象全部来自于另一个数据对象,也就是说该类的构造方法中的参数即另一个数据类对象,因此在该类中所有与被传入对象类中有相同的合法性检查的数据字段不需要再进行合法性检查了。其实这种想法是错误的,问题与上面所说的一样,你能保证传入的数据是合法的,但不能保证使用者在调用你的set方法时能100%传入合法数据。因此,程序员是不应该偷这个懒的。也许有人会说,他们的合法性检查完全一样,如果在该类中再写的话就会出现大量的重复代码了。能想到这里是对的,但是如果你有一定的经验,你就知道去建立一个专门保存合法性检查方法的类,这样你就可以在需要进行合法性检查的时候就使用该类里面的方法,如果该类中没有你所需要的方法,你就可以在里面加入你所需要的合法性检查方法,再去使用它。这样做会使得代码非常的清晰。
我认为,应该在自己类中的所有使用“this.value = data;”字样的代码都应该使用setValue(),因为也许这个字段现在不需要进行合法性检查,但是不能保证将来也没有合法性要求。而一旦以后需要对该字段进行合法检查的时候,就需要在set方法中增加合法性检查代码,而且需要将该类中所有对该字段的赋值语句均改用set方法。一旦有某处漏掉,则很可能带来致命的错误。也许在某个运算中带来了非法数据,但是你却怎么也不会往这方面去想,因为你一直以为自己全部都作了合法性检查的。
|