Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Design by Contract and Bean Validation

DZone's Guide to

Design by Contract and Bean Validation

· Java Zone
Free Resource

Build vs Buy a Data Quality Solution: Which is Best for You? Gain insights on a hybrid approach. Download white paper now!

 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.

Build vs Buy a Data Quality Solution: Which is Best for You? Maintaining high quality data is essential for operational efficiency, meaningful analytics and good long-term customer relationships. But, when dealing with multiple sources of data, data quality becomes complex, so you need to know when you should build a custom data quality tools effort over canned solutions. Download our whitepaper for more insights into a hybrid approach.

Topics:

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

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}