Over a million developers have joined DZone.

Design by Contract and Bean Validation

· Java Zone

Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code! Brought to you in partnership with ZeroTurnaround.

 I must confess that despite all benefits of defensive programming, I usually limit myself to not expose mutable attribute to the outside world. Why is that? I believe this is mostly because of readability. Have a look at the following piece of code:

public List<Person> getPersons() {
    return Collections.unmodifiableList(persons);
}

Easy enough to read and understand. Now, consider a design by contract approach, where I want to enforce pre-conditions, i.e. conditions that have to be met to run the code.

public void sendEmail(String email) {
    Assert.assertNotNull(email);
    // Real code after that
    ...
}

Not really hard. But now, I want to surface-check the email so as not to query the JNDI tree for a SMTP server for nothing.

public void sendEmail(String email) {
    Assert.assertNotNull(email);
    Validator validator = new EmailValidator(email);
    validator.validate(email);
    // Real code after that
    ...
}

It only so much harder to read… for now. Should I have more than one parameter and multiple checks for each parameter, complexity would quickly grow out-of-hand, and this only for pre-condition!. Post-condition checks would take place at the end of the method, and disturb readability even more. Besides, the outside world doesn’t know about those: they have to be manually written in Javadoc and kept in sync with the code.

What if those limitations could be waived? Would I be more inclined toward using design by contract? I do believe that’s the case. And when I attended Emmanuel Bernard‘s talk at Devoxx France, I couldn’t believe usage would be so simple. My goal can be reached by only using Bean Validation API 1.1 (aka JSR-349). This newer version reuses Bean Validation 1.0 (aka JSR-303) annotations, but where in the previous version only attributes could be annotated, now methods can too. Or to say it more generally, before state was validated, now we can design by contract.

The previous method could be updated like so:

public void sendEmail(@Email String email) {
    // Real code after that
    ...
}

You can see by yourself, not only is it more readable but it communicates my intent to the method callers: this should be an email, not just any string. Icing on the cake, the JSR is open, in all senses. You can contribute to the specs, to the implementation, to anything you like!

Kill-joys would probably object that it is nice and good, but it is still in draft. That would be true, except it is nothing like HTML5 scope. Besides, Hibernate Validator was Bean Validation API 1.0 Reference Implementation. It is only natural that it is also the case for version 1.1, with Hibernate Validator 5. However, it already provides everything we need with version 4.2. If you’re willing to use Spring, it is a breeze:

  1. Get the right dependencies in your POM
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>2.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.1.Final</version>
    </dependency>
  2. Annotate your methods as above
  3. Add the right Spring bean post-processor
    @Configuration
    public class SpringConfiguration {
     
        ...
     
        @Bean
        public static MethodValidationPostProcessor methodValidationPostProcessor() {
     
            return new MethodValidationPostProcessor();
        }
    }
  4. Enjoy! Really, it is over, you can use design by contract to your heart’s content.

Sources for this article can be found in Eclipse/Maven format here.

To go further: see relevant links in the article

Note: regular readers of this blog may have noticed I’m using Spring Java configuration whereas I was previously an advocate of XML configuration. Please read this post.

The Java Zone is brought to you in partnership with ZeroTurnaround. Check out this 8-step guide to see how you can increase your productivity by skipping slow application redeploys and by implementing application profiling, as you code!

Topics:

Published at DZone with permission of Nicolas Frankel, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}