Monday, January 30, 2006

A case for Specifications

It has been a long time since I wanted to post about this, and now, finally, here I am.

In this post I want to talk a bit about Specification, a Domain-Driven Design pattern I think very interesting and useful in a lot of situations.

What is, so, a Specification?

Domain models are not only about entities, relations and collaborations. Domain models must also host a lot of implicit concepts and rules you must deal with, because they are important parts of your business domain : for example, booking policies, payment delinquent rules and so on.
The problem is to find a place for this concepts.
You can model and implement them inside your entities, your business objects, but doing so you couple your objects with concepts regarding them but not being part of them; more important :

  • You lose a lot of expressivity, because you sink your meaningful (but implicit) concepts into your object code.

  • You lose a lot of flexibility, because you cannot change or apply them regardless of your business objects.

The answer is the Specification Pattern.

Specifications, as said by Eric Evans, are a concept borrowed from logic programming: they are tiny classes with a method representing a boolean predicate.
The Specification models a particular concept that applies to a particular entity, providing a method which expresses the concept as a predicate; in particular, the method tests if a given instance of the entity satisfies the expressed predicate.

Let me show you a practical example.

Say you have an employee who issues some requests, for example permit requests.
The employee cannot directly request a permit for a number of days greater than those remaining; if he wants to request more days, he must ask the secretary, but even in this case he cannot exceed a certain limit.

How do you model this?

You'll have an Employee entity, a generic Request and a PermitRequest entity.
But what about all those concepts regarding the employee request?
Remember, a permit request which exceed the employee remaining days is not valid if made by the employee, and so on ...

If you don't use Specifications, you can implement a validation method inside your PermitRequest class :
public class PermitRequest
implements Request, ValidationAware {
private static final int limit = -10;
private Employee owner;
private int requestedDays;
// ...
public void validate() {
int remaining = owner.getRemainingDays();
if (remaining < this.requestedDays) {
// notice this ...
}
if ((remaining - this.requestedDays)
< PermitRequest.limit) {
// notice this ...
}
// ...
}
}
Doing so, however, you couple your rules and cannot separately apply them, breaking your requirements!
You can surely use two distinct validation methods:
public class PermitRequest
implements Request {
private static final int limit = -10;
private Employee owner;
private int requestedDays;
// ...
public void validateForEmployee() {
int remaining = owner.getRemainingDays();
if (remaining < this.requestedDays) {
// notice this ...
}
// ...
}
public void validateForSecretary() {
int remaining = owner.getRemainingDays();
if ((remaining - this.requestedDays)
< PermitRequest.limit) {
// notice this ...
}
// ...
}
}
But doing so you couple yourself with the particular Request entity, breaking a lot of design principles ... what if we want to validate a request without knowing its actual type? What method to call?

Implementing two distinct Specifications is simple and solves all your problems.
You'll have an ExceedDaysSpecification for the first rule (requested day cannot exceed remaining days), and an ExceedLimitSpecification for the second one (requested days cannot exceed a certain limit), each with the predicate method accepting a Request and testing the given rule over it.
public class ExceedDaysSpecification
implements RequestSpecification {
public boolean isValid(Request request) {
int remaining = request.getOwner().getRemainingDays();
int requested = request.getRequestedDays();
if (remaining < requested) {
return false;
}
else {
return true;
}
}
}

public class ExceedLimitSpecification
implements RequestSpecification {
private static final int limit = -10;
public boolean isValid(Request request) {
int remaining = request.getOwner().getRemainingDays();
int requested = request.getRequestedDays();
if ((remaining - requested)
< ExceedLimitSpecification.limit) {
return false;
}
else {
return true;
}
}
}
In this way :

  • Implicit concepts are powerfully expressed.

  • Specifications can be applied to every base type of entity (Request) : if you need to know the actual type inside the Specification predicate method, you can do a downcast or apply a simplified Visitor pattern.

  • Specifications can be easily combined : simply combine the evaluation of the predicate methods!

You have the obvious drawback of having to implement a given quantity (maybe a lot, for complex domains) of small classes, but I think the gained expressivity and flexibility well worth the effort.

What's your way of thinking about this?

Friday, January 20, 2006

Google, finally!

Google finally hit the target, again.

Now, if you search for "sergio bossa blog" you'll get my personal blog (yes, this site) as its first result.

I'm very well-satisfied ... don't you see?

Thursday, January 19, 2006

A funny quote ...

I can't help but laughing about this:

The March of Progress

1980: C

printf("%10.2f", x);

1988: C++

cout << setw(10) << setprecision(2) << showpoint << x;

1996: Java

java.text.NumberFormat formatter = java.text.NumberFormat.getNumberInstance();
formatter.setMinimumFractionDigits(2);
formatter.setMaximumFractionDigits(2);
String s = formatter.format(x);
for (int i = s.length(); i < 10; i++) System.out.print(' ');
System.out.print(s);

2004: Java

System.out.printf("%10.2f", x);

Found here.

Tuesday, January 17, 2006

Teaching Object Oriented-ness

OK, new year, old life, and very poor free time for posting or enjoying a lot of new technologies waiting for me and requesting my attention!!!!

I should find more time .... no, correct myself .... I MUST find more time!!!!
Repeat, please : more time, more time, more time ..... !!!!

However, I don't want to talk about this, but rather about what happened to me some days ago: in fact, last week I started my first, true, teaching experience.
I started teaching Object Oriented Design & Programming in Java to a class of eight: I am very passionate about object oriented design and I totally devoted myself in communicating them OO principles, achieving also good results.

The eight would-be OO Java developers had all a strong Visual Basic 6.0 background, and what mostly surprised me was how many bad habits this sort of programming language embed in whoever is exposed to it for a lapse of time greater than, say, one year.

Visual Basic literally destroyed a generation of programmers.

Moreover, I truly discovered how difficult is to move from procedural way of thinking, to object oriented one, and how difficult is to solve a problem in object oriented fashion.

However, this should not surprise myself, because I know a lot of developers who, while using Java or C++, don't really develop in OO and maybe don't fully understand it.

I think that object oriented design (and programming) is one of that things which everyone theorically praise but practically (almost) never do.
And this is very bad, and this is the reason why many projects literally go spaghetti.

This is why I'm starting to love Domain-Driven Design .... but this is another story.

Which maybe I will tell you some day.

Monday, January 02, 2006

A New Year

Another year passed fast.

Another year starts to pass.

For our memories.

Shantih shantih shantih.
(T.S. Eliot, The Waste Land, verse 433)