Implementing Command Pattern using Spring injection

  • Sharebar

Recently I was working on a user story and after the initial design and a bit of implementation, I noticed that the code is not organised nicely and also making my life hard from the unit testing standpoint.
The business problem my code addressed was building a rule engine (built with a set of validation rules)  that is applied on the input from the client , generate warning, error messages and validating the input.So, this is how I designed my implementation at first

class Validator {
 ValidationResult result;

 public ValidationResult validate(input){
   rule1();
   rule2();
   rule3();
   ---
   ---
 }

 private rule1(){
   doSomething...
 }
 private rule2(){
   doSomething...
 }
 ...and so on.
}

At first when I read the user story documentation, I had to apply 4 rules in all, but think of a scenario when the user has a couple of more rules to be applied on the input now and wants to take out a few which we implemented in the first place , what would u do now?

Add 2 more private methods named rule5 and rule6 to Validator and add a call to both in the validate method , also take out method rule1(since that rule has become obsolete now)
Now, because I had only one method exposed from Validator,the unit test case(called ValidatorTest) also broke and I had to capture the scenarios covered by the two new rules added and remove the obsolete one.

Looks clumsy , doesn't it?, I thought of a better design approach from the clean code and unit testing perspective and came up with the following design

Validator now would only have one method called validate and no private methods inside it , since all the rules take input as a parameter and return validation result as the output, created the following interface

interface ValidationRule {
   ValidationResult validate(input,result);
}

I pulled out all the private methods from Validator and created a class for each one of those with the following implementation

Note : result is an instance of ValidationResult only

class Rule1 implements ValidationRule{
   public void validate(input,result){
    [business logic here .....];
   }
}

class Rule2 implements ValidationRule{
   public void validate(input,result){
     [business logic here .....];
   }
}

and so on ...

Lets plugin these into Validator ..I used spring's dependency injection in following way
My Validator class would look like

class Validator {
ValidationResult result;
List<ValidationRule> rules;

    public void setRules(List<ValidationRule> rules){
     this.rules=rules;
    }
    public ValidationResult validate(input){
       for(ValidationRule rule:rules){
         rule.validate(input,this.result);
    }
 }
}

In the application-context.xml I added following

<bean id="validator">
 <property name="rules">
   <list>
     <bean class="com.xebia.business.rules.Rule1"/>
     <bean class="com.xebia.business.rules.Rule2"/>
     <bean class="com.xebia.business.rules.Rule3"/>
     -----
     -----
   </list>
 </property>
</bean>

I added unit test cases for all the rules as Rule1Test, Rule2Test e.g., independent of one another.

Benefits that I see with this design are following

1. Cleaner code , Validator is now acting as a proxy for the rules engine and doesn't contain any business logic.

2. Enhanced testability , all the rule classes can be tested independent of each other.

3. In future if a rule becomes obsolete , I'll just remove that from the <list> tag in the context file and similarly if new rules need to be added, just add a rule class without touching either Validator and any of the Rule classes and put an entry in the list tag in the context file.

Share the bee buzz:
  • Digg
  • del.icio.us
  • Facebook
  • DZone
  • LinkedIn
  • StumbleUpon
  • Technorati
  • Twitter

One Response to “Implementing Command Pattern using Spring injection”

  1. Thanks for sharing your idea…for long number of days I was looking for this type of clean code example with a real life problem…..
    Thanks ……

Leave a Reply