Using Decorator (or Wrapper) Design Patterns to add Validation to an object

Context

In most cases when someone write about the Decorator pattern it is usually related to UI stuff. The most common example is adding “decoration” to a control, for example a scroll bar. But in my humble opinion, this is not the most useful usage of Decorator. The purpose this pattern is:

“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality”

Gang of Four

If you think about it, Validation is a responsibility and so it can be added by this pattern. Of course we can add the validation to the class itself or in its base class, but how would you reuse this validation across many unrelated objects and what if you object must derive from another base class?

Solution

Decorator The solution is the Decorator pattern. With this pattern we can add new responsibility to an object without changing its internals.

For simplicity purpose we will take a simple sample that anyone can understand but the concept shown here can apply to much more complex object.

Four our sample we will take a bank account. On this account we should be able to to money deposit and withdraw. The class diagram on the right illustrate this design.

Let’s start by defining our IAccount interface

This simple interface will be the central abstraction of the system. The goal is to never depends on concrete class and this interface in enough to add a lot of functionality around an account.

Now here the interface implementation as an Account:

If you expand the previous block of code you will see that the implementation of IAccount is only doing business stuff. There is no other responsibility in this class than the one that is meant for. We can clearly see “Template Method” design pattern here. All “OnSomething()” method are protected and any derided class can add implementation around the process. All “Before” method can cancel the process if the return value is false. This allow extension classes to add some specific behaviour.

But one of the main thing missing in this class is “validation”. We will use the decorator pattern to do that. A decorator class is a class thst implement all the member of an abstraction and forward all the calls to an internal instance of a real implementation that abstraction. In our case the abstraction is “IAccount” so we have to make a decorator that implement that interface.

As you can see the constructor of the decorator takes an instance of “IAccount”. All method forward their call to that instance. This base class simplifies the process of creating concrete decorator by allowing other decorator to implement some but not all members of the interface.

Now is the time to start implementing our validation class structure. For that purpose we will create a base validation class that will be responsible of applying the validation the IAccount instance.

This simple base class define a “GetValidations” method that all derived class must override to add a list of validation to perform on method call.

Now to implement the “Deposit” validation we have to create this class:

This class is responsible for creating all validation instances. The “Deposit” method is overridden to call the base “Validate” method before doing the actual deposit.

To implement those validation we need to define the “IValidation” interface.

Here is a sample implementation:

All other validations used in “AccountDepositValidator” can be described the same way.

The last step is to create an actual “IAccount” that will implement all this stuff. To do that we will need a Bank class. A bank is responsible of creating account. It will also be responsible of decorating it with all necessary decorators.

To illustrate this process in action here is a sequence diagram:

Validation with Decorator

  1. Call Bank.CreateAccount.
  2. The Bank instantiate an Account class.
  3. The Bank create an AccountDepositValidator and wrap Account with it
  4. The Bank return an instance of IAccount.
  5. Deposit is called on IAccount which is an instance of AccountDepositValidator
  6. AccountDepositValidator call Validate
  7. AccountDepositValidator call GetValidations to retrieve the list of validation to evaluate
  8. An AmountGreaterThaZeroValidation is created
  9. IsValid returns true
  10. AccountDepositValidator call base Deposit method
  11. Balance value is updated

Next

With all this in place the only thing left to do is to implement all the other validators for all method of “IAccount”.


7 thoughts on “Using Decorator (or Wrapper) Design Patterns to add Validation to an object

  1. AccountDecorator has a few issues, firstly: all of the properties/methods refer to _account as Account which would be incorrect since that would be a static member to the Account class. I assume this was an oversight as you were typing up your blog post.

    The more pressing issue is why does AccountDecorator exist at all? You could have easily have just used the original account since there was no purpose to your decoration of it. Or you could’ve created something like

    IValidatorMember&ltT&gt class

    and instead of AccountValidatorBase : AccountDecorator you would use

    AccountValidatorBase : IValidatorMember&ltIAccount&gt

    I think it’s much more preferable for wrapper classes to be implemented through generics so you don’t end up with double the amount of files per classes you have.

Leave a Reply