首先,就像你在代码里看到的那样,我们从值对象里取得所有的方法。然后,我们遍历所有方法的集合。如果方法以get开头,便是AbstractParameter的子类型,而不是可选择的方法。我们通过反射调用getter方法,并且检测它的结果。如果结果是null,那么这就是一个错误;如果不是,便是正常情况。那些可选择的方法和继承自父类的方法不会被执行。
测试我们的类
现在,我们实现了我们所需要的所有的类和接口。我们必须做一些测试来检验我们的类是否能够正常工作。为了做到这一点,我们写了一点小的测试类和一个main方法来运行测试。
TestParameter
TestParameter类继承自AbstractParameter,并且包括了一些需要校验的私有属性:很简单的4个Integer属性。
Optional attributes
为了识别可选的属性没有被检测,我们定义了为属性:testParam3可选的getter方法。为了这个目的,我们通过TestParameter的构造器里的addOptionalMethod(methodName)方法将这个getter方法输入到父类AbstractParameter的可选方法map里。
校验框架是如何工作的
为了测试,我们在TestParameter里使用如下方式输入:
TestParameter param = new TestParameter( );
param.setTestParam1( new Integer( 1 ) );
param.setTestParam2( new Integer( 2 ) );
param.setTestParam3( new Integer( 3 ) );
param.setTestParam4( new Integer( 4 ) );
就像你所看到的那样,4个Integer属性记作Integer1,2,3和4。为了校验,我们仅仅调用:param.validateWith( GenericClassAttributeValidator.getInstance( ) );
这个校验的结果是:
testParam1: 1
testParam2: 2
testParam4: 4
testParam3属性没有被校验,因为我们记录了它的getter方法为可选的。其他所有的方法得到了校验,并且结果是正常的。现在,我们希望看到其中的一个属性值为空,这样我们就能检测是否validator能够检测到这个错误。我们注释掉下面的行:
param.setTestParam2( new Integer( 2 ) );
我们重新开始测试以后,得到如下的结果:
testParam1: 1
Error: testParam2 in TestParameter is null!!!
testParam4: 4
现在我们看到了validator已经检测到了这个没有赋值的属性。
如果属性类型为集合类型,将会怎么样呢?
如果属性类型为集合,它仍然会检测这个集合是否为空。但是,可能检测集合是否为null并不是你想要的。在大多数情况下,你希望检测集合里的对象是否为null。如果集合的实现不允许null对象,你不需要关心这些在GenericClassAttributeValidator里的null对象继承自AbstractParameter。一些为集合保持继承自AbstractParameter的对象的辅助代码看起来如下所示:
if ( methodResult instanceof Collection )
{
Collection col = (Collection) methodResult;
Iterator iter = col.iterator();
Object subParam = null;
while ( iter.hasNext() )
{
subParam = iter.next();
if ( subParam instanceof AbstractParameter )
{
AbstractParameter abstractParam = ( AbstractParameter ) subParam;
abstractParam.validateWith( this );
}
}
}
集合里的所有没有继承自AbstractParameter类的对象没有被检测,因为我们将使用一个不允许null对象的集合实现。所以集合实现为我们完成了检测。如果你决定使用一个允许null对象的实现,那么为while循环的所有其他的对象的一个额外的null检测就是必须的了:
else if( subParam == null )
{
System.out.println( "Error: SubParameter not set in Collection!" );
}