Understanding the concept of Convention over Configuration

Software development has come a long way in the past 10 years. There are some great concepts that innovated and streamlined the way we develop custom software and there are other concepts that most of us would like to forget. Some of the latter things include heavy, process intensive software methodologies, proprietary software packages that don’t adhere to standards and home-rolled architecture that just doesn’t want to die. On a more positive note, the past few years have brought Test Driven Development, complexity measurements, more open standards and one of my personal favorites is convention over configuration.

Simply, convention over configuration is the ability to use coding conventions to achieve the same functionality that external configuration did before. Let me give you several examples using some of my favorite frameworks.

Spring

In Spring, convention can be used to define Spring Beans, Autowiring and many of the concepts that before required lots of XML glue. The benefit of this being that you can look at a POJO class and determine exactly what is is used for without having to go digging in an XML file for the “glue code”. Using simple annotations to demarcate Services, Utilities, DAOs, etc, eliminates the amount of XML that you have to write and maintain.

Struts

Struts is a little late to the convention game, but if you are familiar with Struts, you probably are familiar with many XML files you maintain to map your actions. The Struts convention plugin eliminates the need for all this XML by using annotations to defined your mappings.

Junit and TestNG

While testing doesn’t involve configuration so much as the previous examples, we gain another benefit here. Previously all test cases needed to extend a parent test class, but no longer. Junit, Unitils, TestNG, DBUnit have all had the ability to use a “Zero Configuration” option for some time just by annotating simple Pojo classes.

Hibernate and Java Validation

I saved the best for last here. Hibernate embraced annotations early, allowing developed to move away from hbm.xml files. Also, when you couple this with the power of the Java Validation Framework, you get a persistable domain model that has built in validation, all in once centralized location, ideal if you have multiple front ends sharing the same common codebase.

“Zero Configuration” is another term that is often used to describe a convention-driven design.

Annotations are relatively new to most developers, even thought they have been used in both Java and C# for several years now. Annotations are simple a way to self document code.

Convention-driven over a configuration-driven design has several benefits.

1. Faster to develop
2. The code is self explanatory
3. Easier to maintain, thus reducing the cost of ownership
4. It’s cleaner and easy to understand
5. Easier to refactor. (Automated refactoring tools very often butcher XML configuration files)
6. Easier to learn for newer developers. (It’s the change-resistant older-developers who usually find it difficult to make the switch)

Now that you know the benefits of a convention-driven design, you should take a look at your own frameworks and see if there is a way to accomplish it. I recommend looking heavily at Spring to start the discovery process and it has a near flawless implementation of this paradigm.

Haven’t got the time? Joda Java Date-Time framework does….

Raise your hand if you have a DateUtil class or you wince every time you have to work with Java dates. Now ask yourself are you the type of person who would rather struggle around with it and write it yourself or are you enterprising enough to look for another solution. I know most Java developers complain about framework fatigue these days, but I wouldn’t trade the hundreds of frameworks out there just to have to go back to the days when I had to do it all myself. Joda Java Date Time framework is a great example of why I like frameworks.

Joda has all the date utilities you will ever need to manipulate time and dates in Java. Let’s take a look at some of the examples straight from the framework’s web site.

public boolean isAfterPayDay(DateTime datetime) {
if (datetime.getMonthOfYear() == 2) { // February is month 2!!
return datetime.getDayOfMonth() > 26;
}
return datetime.getDayOfMonth() > 28;
}

public Days daysToNewYear(LocalDate fromDate) {
LocalDate newYear = fromDate.plusYears(1).withDayOfYear(1);
return Days.daysBetween(fromDate, newYear);
}

public boolean isRentalOverdue(DateTime datetimeRented) {
Period rentalPeriod = new Period().withDays(2).withHours(12);
return datetimeRented.plus(rentalPeriod).isBeforeNow();
}

public String getBirthMonthText(LocalDate dateOfBirth) {
return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH);
}

After I found Joda time I gutted my DateUtil class and just had the implementations of the utility methods call Joda features. The framework is extremely rich and it has several benefits, two of which are;

1. It simplifies the manipulations of Date and Time in a logical way
2. It alleviates the performance penalties that result from improper use of the Date and Calendar objects in Java.

So as I have said many times, don’t reinvent the wheel. Go grab the Joda time jar and toss all that crappy code in your DateUtil…I did….

Struts 2 isn’t Spring 3 but its darn close

By Chris L Hardin
Sr. Software Architect

Five years ago I wrote off Struts in favor of Spring MVC and with good reason. I was already using Spring for a myriad of other things and it was just logical to use the MVC portion since it had all the niceties that I came to expect from Struts, plus a lot more. Also, after Spring 3 came along, I think I decided there couldn’t be anything farther from perfection.

I started using Struts when it was still in its infancy and I used it on more than 20 projects, some of which were really high profile like the Toyota and Lexus Web sites. Struts was the solution to all these home-rolled frameworks that other architects were writing at the time. I think at this point all of those in-house solutions have been replaced by some Web framework by now or at least I hope they are.

I enjoyed Struts while it was in its heyday and I still think it dominates as the most widely used and accepted framework even today. All this being said, I haven’t seen anything Struts can do that can top Spring 3 though.

Recently, I had the pleasure of working on a project that was full-blown Struts 2 and I kept saying things like, “This is a new project, why are we using Struts.” and “Struts is dead…move on.” I was wrong.

Struts 2, which is actually WebWork rebranded as Struts, is a different animal. A pretty well designed framework that does a good job of creating a MVC architecture. It has all the features you have come to expect from Struts, along with a plugin framework and much, much more.

Struts 2 is still configuration heavy and I am pretty disappointed in that, but there is a convention plugin that allows you to use annotations and there is a JSON plugin as well that is really useful. All in all, I think there are around 30 plugins or more in Struts 2 that you can use.

Since I really love Spring 3 and conventional configuration options, I decided I would share some of my Struts 2 + Convention plugin configurations and code.

Simply, the convention plugin annotations allow you to use the “Zero Configuration” option for Struts 2, which I highly recommend. If you are still gluing your actions together with the struts.xml, you really need to stop overworking yourself. Let’s look at some examples of creating actions by convention.

The app that follows is an app for searching up and displaying users using either Ajax forms or an HTML form. The options you have are to return another page or just to return the JSON data.

I only have one class for this example and here is the declaration.


@ParentPackage("json-default")
@Namespace("/")
public class DefaultAction extends ActionSupport implements
ModelDriven {

Our UserSearch object contains just setters and getters for your form like get/setFirstName, etc. The UserSearch object is also annotated using the Java Validation Framework annotations. We implement ModelDriven so that we can externalize our form bean properties away from our action. We also extend ActionSupport so that we can add error and validation messages. I do not like having to extend ActionSupport just for the sake of adding messages because my object is no longer a POJO at that point. I couldn’t find anyway to add messages without extending this class.


@Action(value = "Start", results = { @Result(name = "success", location = "start.jsp") })
@Override
public String execute() {
...

private UserSearch search = new UserSearch();

@Override
public UserSearch getModel() {

return search;

}

Our first action is simple. Someone asks for /Start and we execute and redirect to start.jsp if success is returned.


@Action(value = "Process", results = { @Result(name = "success", location = "start.jsp") })
public String process() {

Set<ConstraintViolation> violations = search
.validate(search);
for (ConstraintViolation violation : violations) {
addActionError(violation.getPropertyPath() + " "
+ violation.getMessage());
}

In our form, we submit to /Process and since we have annotated the UserSearch with the Java Validation Framework, we can now validate the object. Struts 2 has built-in validation,. but I prefer to use the Java standard. If there are any constraint violations, we add them to action messages and they get returned to the client to display in the JSP page if you are using the correct tags from Struts.


@Action(value = "json", results = { @Result(name = "success", type = "json"),
@Result(name = "error",location = "start.jsp") })
public String executeAsJSON() {

Just in case you wanted to return the results of the search as JSON, you can do this in Struts 2. This will return the Model represented as JSON. This doesn’t do you much good in this case because the model is what we passed in the form, a UserSearch object. I got around this by putting a new property on UserSearch called UserSearchResult which contains the results of the search. In the executeAsJSON method, I merely call getModel().setUserSearchResult(result) and then I can access the results in JSON. In Spring 3, I could have set the return type of the method to UserSearchResult and solved the problem, but I couldn’t figure out in Struts how to do this or I don’t know if it is even possible yet, so I settled for my little hack.

I know I said that there was nothing in the struts.xml, but I didn’t exactly tell the truth. I did set some configuration options in the file.

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<!---->

<!-- -->

<!-- -->

<!-- -->
<!-- -->
<!-- -->
<!-- -->

<!-- -->

<!---->

I’m not going to go into an explanation of these properties. They are kind of self explanatory anyway.

There is also another great plugin for Struts 2 for Spring integration. It allows you to use @Autowire in your actions to automatically inject the value of a bean from Spring into the action. This is very useful, but if you’re already using Spring, you’ll probably use the more flexible Spring 3 features instead of Struts anyway.

I have to say that I love Struts 2 and you really can’t go wrong by choosing it for your MVC framework. I will add though that some more work needs to be done on supporting the convention-based options. Some of the things I would like to see are the ability to easily just let the return type be anything and have the framework convert it to JSON and I’d like to see content negotiation whereby I can change the output of the method from json to XML to PDF to Excel, just by requesting a different extension.

All in all Struts may be an old dog, but it certainly has learned some new tricks.