Vikas Gupta: Software architect

Domain Driven Design : Making Implicit concepts Explicit

Posted by Vikas Gupta on January 6, 2010

In the previous post, I discussed about how to query the domain objects. That post completes the issues with domain object lifecycle management. In this post, I will discuss how to make implicit concepts explicit in order to make domain model more expressive

Sometimes small details of the design get lost in the code. We tend to consider small business rules and constraints as implicit and these details are not given enough importance as they should be given.They are often coded as a bunch of if-else blocks in the code and this makes the identification of these business rules difficult and more importantly makes design less effective. Let see some of the concepts/design patterns which can be used to make these implicit concepts more explicit.

Specification

Most application have small rules which are evaluated as boolean value. Some of these can be simple. But, there are certain rules which are fairly complex. They are infact, a combination of one or more of such smaller business rules. Sometimes, these rules are applicable on multiple objects and can be complex enough to make their prescence felt and it is advisable to factor them out in a separate class or method. Such business rules can be termed as Specification as test any object to see whether it satisfies the specified criteria. Let’s see the example of a specification.

class OverdueInvoiceSpecification extends InvoiceSpecification {
   private Date currentDate;

   public OverdueInvoiceSpecification(Date currentDate) {
      this.currentDate = currentDate;
   }

   public boolean isSatisfiedBy(Invoice invoice) {
      int gracePeriod = invoice.customer().getPaymentGracePeriod();
      Date deadline = invoice.dueDate() + gracePeriod;

      return currentDate.after(deadline);
   }
}

Now, we can simply apply the rules wherever, we want

class CustomerAccount {
  boolean isOverDue() {
   Specification overDueSpec = new OverdueInvoiceSpecification(new Date());
   Iterator<Invoice> listInvoices = customer.getInvoices().iterator();
   for (Invoice invoice : listInvoices) {
     if (overDueSpec.isSatisfiedBy(invoice)) return true;
   }
   return false;
  }
}

There can be many places which warrant the use of specification pattern in an application. Mostly, they are used in

  • Validations, as demonstrated above
  • In filtering data, based on business rules. For doing this we can combine Repositories with Specifications and filter data returned from the persistent storage
  • In domain object security. We can check using specification whether a particular object is editable by a user with specified role. Spring security provides a more sophisticated framework for this.

There is no doubt that factoring out methods and classes for these business rules makes design more expressive, but, there can be numerous such rules in the code and factoring a separate places for each of them can be quite cumbersome. So, how to decide when to create a new method or class for a business rule or constraint.  I think the key lies in the word business. If a condition affects a business decision, it is a business rule and we can model them separately in a method or class. Moreover, if the specification code in itself is bit involved and can be applied as multiple places, it is better to separate them out of the domain object.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: