2013-01-24 50 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