30

I am reading the brilliant book "Domain Driven Design" written by Eric Evans. In his book Eric describes two different concepts: the specification pattern and policies.

Here is an example for a specification:

public interface ProjectSpecification {
  public boolean isSatisfiedBy(Project p);
}

public class ProjectIsOverdueSpecification implements ProjectSpecification {
  public boolean isSatisfiedBy(Project p) { … }
}

//client:
if {
  (projectIsOverdueSpecification.isSatisfiedBy(theCurrentProject) { … }
}

Here is an example for a policy:

public class CargoBooking {

  private OverBookingPolicy overBookingPolicy = new OverBookingPolicy();

  public int makeBooking(Cargo cargo, Voyage voyage) {
    if (!overbookingPolicy.isAllowed(cargo, voyage)) 
      return –1;
    int confirmation = orderConfirmationSequence.next();
    voyage.addCargo(cargo, confirmation);
    return confirmation;
  }
}

public OverBookingPolicy {
  public boolean isAllowed(Cargo cargo, Voyage voyage) {
    return (cargo.size() + voyage.bookedCargoSize()) <= (voyage.capacity() * 1.1);
  }
}

I know that a policy is actually a strategy but in the two examples above there is absolutely no difference. So my question at this point is: What is the difference between those two patterns? Both patterns make business rules explicit so why do we distinguish between those two patterns? For me both are kind of predicates.

Chris Moutray
  • 16,972
  • 7
  • 43
  • 63
MUG4N
  • 18,011
  • 10
  • 52
  • 81
  • I would say that specifications are targeted on describing features of instances and policies are about describing actions. But I'm really not sure about, although I also read the book. – SpaceTrucker Jan 06 '13 at 18:14

1 Answers1

57

The main idea behind SPECIFICATION is that it's a predicate, which often implies using logical operators with it

SPECIFICATION is an adaptation of an established formalism (Eric Evans DDD, p. 274)

for example we can say that the box is red, i.e. satisfies some RedSpecification. We can declare some GreenSpecification, and even a composite RedOrGreenSpecification. If we have some advanced framework that supports logical operations for specifications it can be something like

BoxSpecification redBoxSpec = BoxSpecification.forColor(BoxColor.RED);
BoxSpecification greenBoxSpec = BoxSpecification.forColor(BoxColor.GREEN);
BoxSpecification redOrGreenBoxSpec = redBoxSpec.or(greenBoxSpec);

then we can use the specification for example to query all red/green boxes from some repository:

Collection<Box> boxes = boxRepository.findAll(redOrGreenBoxSpec);

As for POLICY - it's a variant of STRATEGY pattern, but its main purpose is encapsulating the business rules is some declarative form.

Technically - it's not always a direct implementation of STRATEGY - in first stages it can be just a separate class(as it's shown in the first chapter of the blue book), but it can be easily extended later

Policy is another name for the design pattern known as STRATEGY It is usually motivated by the need to substitute different rules, which is not needed here, as far we know. But the concept we are trying to capture does fit the meaning of a policy, which is an equally important motivation in domain-driven-design

For example we pack presents in yellow boxes in January, and in red boxes in February

public class Box{
  public BoxColor getColor(){}
  public void recolor(BoxColor color){} 
}

public class BoxFactory{
    public Box createDefaultBox(SomeDate date){
         NewBoxPolicy boxPolicy = PolicyRegistry.getNewBoxPolicyForDate(date);
         Box box = new Box();
         boxPolicy.prepareBox(box);
         return box;
   }
}
public interface NewBoxPolicy{
   void prepareBox(Box box);
}
public class FebruaryNewBoxPolicy implements NewBoxPolicy{
    public void prepareBox(Box box) { box.recolor(BoxColor.RED}; }
}
public class JanuaryNewBoxPolicy implements NewBoxPolicy{
    public void prepareBox(Box box) { box.recolor(BoxColor.YELLOW}; }
}
public class PolicyRegistry{
   public static NewBoxPolicy getNewBoxPolicyForDate(SomeDate date){
      switch (date.month()){
         case SomeMonth.JANUARY: return JANUARY_NEW_BOX_POLICY;
         case SomeMonth.FEBRUARY: return FEBRUARY_NEW_BOX_POLICY;
         default: throw new AssertionError();
      }
}

It's important to understand that POLICY can encapsulate actions, while SPECIFICATION only describes the properties of an object(these properties can both satisfy or DO NOT satisfy the business requirements). Some validation POLICY can use SPECIFICATIONs to check that the requirements are satisfied, of course.

So you can have many different SPECIFICATION instances in your project, and they can describe both the valid and invalid objects from the business point of view. Actually, specifications can make no sense at all: for example if you have a product searching site, user can specify a request to search for a product named "XBOX", but with the vendor name "Sony", if the knowledge that only the specific vendors can produce the specific products is not captured in your model.

The important aspect of POLICY is that its intent is to encapsulate the actual business rules(so the code is not scattered the different parts of the project), so when the rules change you can easily find the corresponding class. So you can have many SPECIFICATIONs in your project, but a manageable number of POLICIES, and those POLICIES should be easy to find and to change.

P.S. please note that this post is just an example and not a license to do over-engineering, of course you should use the simplest design possible, it's a matter of common sense.

tavnab
  • 2,226
  • 15
  • 24
Boris Treukhov
  • 16,478
  • 9
  • 66
  • 86
  • 1
    Let me get this right. A policy contains algorithms. Specifications are predicates and therefore limited to boolean checks. Did I get this right? (to put it simple) – MUG4N Jan 06 '13 at 20:58
  • 3
    @MUG4N yes - that is the difference between them, but the coolest feature of SPECIFICATION is composition, and the feature of POLICY is that the code that contains the business rules is not scattered (encapsulation) I.e. it's ok to have a lot of the specs(and their combinations) all over the place, but it's not ok to have a lot of policies without some centralized place where you can find them. – Boris Treukhov Jan 06 '13 at 21:06
  • 2
    @BorisTreukhov impresive explanation – E-Bat Jan 30 '15 at 22:20