简体   繁体   中英

Best practice TDD - Java Object Validation and clean code

Suppose a Java class called Car , whose objects are initialized through a static factory:

public class Car {

    private String name;

    private Car(String name){//...}

    public static Car createCar(String name){
        //mechanism to validate the car attributes
        return new Car(name);
    }
}

Of course, I want to extract Validation process into a dedicated class named CarValidator .

There are two ways of providing this validator to the factory:

Not stubbable/mockable validator :

public static Car createCar(String name){
     new CarValidator(name); // throw exception for instance if invalid cases
     return new Car(name);
}

Stubbable/mockable validator:

public static Car createCar(CarValidator carValidator, String name){ //ideally being an interface instead
    carValidator.validate(); 
    return new Car(name);
}

It look likes a redundancy here: CarValidator already contains name value since it stores Car parameters as its own fields (a priori cleanest way), thus we could bypass the second argument like this:

public static Car createCar(CarValidator carValidator){ 
     carValidator.validate();  
     return new Car(carValidator.getName());
}

However, this looks unclear... why would a Car find its values from a Validator => no sense.

So, we could refactorate like this:

public static Car createCar(CarValidator carValidator, String name){ 
                        carValidator.validate(name); // throwing exception for instance if invalid cases
                        return new Car(carValidator.name());
}

Sounds pretty less weird, but CarValidator looses the benefit from creating fields rather than passing arguments to each of its necessary private methods like:

private checkForCarName(String name); 

Which method should I choose?

My proposition is following: I would not mix validation of domain object with the object itself.

It would be a lot more cleaner if domain object would assume that the data passed to it are valid, and validation should be performed somewhere else (eg in a factory, but not necessary).

In that "factory" you would perform data preparation state (validation, vulnerability removal etc.) and then you would create a new object.

You will be able to test the factory (if it is validating properly) and not the domain object itself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM