2013-01-24 49 views
8

我想在将它们传递给系统的其他部分之前验证我的域对象。我想验证的所有对象共享相同的接口。问题是,我无法弄清楚如何以良好的方式写出这些。我不想在我的值对象中移动验证。但我不想被迫做一个实例检查。验证java中的值对象(继承)

一个例子:

public interface Vehicle {} 

public class Car implements Vehicle {} 

public class MotorBike implements Vehicle {} 

public interface VehicleValidator { 
    void validate(); 

} 

public class CarValidator implements VehicleValidator { 

    @Override 
    public void validate() {} 
} 

public class MotorBikeValidator implements VehicleValidator { 

    @Override 
    public void validate() {} 
} 

public void process(Vehicle vehicle) { 
    //TODO: validate vehicle 
    doSomething(vehicle); 
} 

在Scala中我会做类似http://debasishg.blogspot.se/2010/06/scala-implicits-type-classes-here-i.html 但这些语言结构的东西是不可能在Java中。

+2

这听起来很像你问关于[*访问者模式*](http://en.wikipedia.org/wiki/Visitor_pattern)。 –

+0

为什么你不想将验证方法放在值对象中?实际上,即使您清理了接口层次结构,您仍然需要链接验证器实现,以支持值对象的自然层次结构。 – Perception

+0

出于好奇,是否有这样一个理由反对在这种情况下使用instanceOf? – Zylth

回答

0

你最好打赌的是一个战略模式imo,但是这不会让你远离做instanceof/isAssignableFrom检查。但是,如果您构建得好,至少可以将它抽象出来,一般地处理它,而且如果添加其他车辆类型,则不必担心添加其他检查。

我能去解释策略模式,但它在这里做更好:http://www.javacodegeeks.com/2012/04/strategy-pattern.html(弹簧)

许多框架将有类外的即装即用,方便这一点。

2

这是Double Dispatch设计模式的经典案例。

您需要添加的回调代码一点点的车辆,将在运行时动态绑定验证器的适当的方法:

public interface Vehicle { 
    void validate(Validator validator); 
} 

public class Car implements Vehicle { 
    public void validate(Validator validator) { 
     validator.validateCar(this); 
    } 
} 

public class MotorBike implements Vehicle { 
    public void validate(Validator validator) { 
     validator.validateMotorBike(this); 
    } 
} 

public class Validator { 
    public void validateCar(Car car) { 
     // validate a car 
    } 

    public void validateMotorBike(MotorBike motorBike) { 
     // validate a motorbike 
    } 
} 

public void process(Vehicle vehicle) { 
    Validator validator = new Validator(); 
    vehicle.validate(validator); 
    doSomething(vehicle); 
} 
+0

但是从问题中的代码来看,验证是车辆子类型特定的。 – Taylor

+0

@泰勒OMG。这就是这个代码所做的!我编辑了代码并更改了方法名称并添加了评论以帮助澄清 – Bohemian

+0

我一定错过了一些东西,现在我看到了。我的derp。 – Taylor