Showing posts with label patterns. Show all posts
Showing posts with label patterns. Show all posts

Wednesday, 9 December 2009

Immutable Wrapper

I am a huge fan of immutables, especially for value objects. Even in clumsy static languages like C# and Java that seem to throw every obstacle in your way to deter you from using them I find the benefits outweigh the costs.

Sometimes though a mutable makes sense. Whether that's because of the restrictiveness of a framework or the paradigm of the language. But what if we don't want to loose the power of immutables behind the scenes?

Introducing The Immutable Wrapper Pattern!

The Immutable Wrapper is a wonderfully simple pattern because there are only two things you need to do.
  1. Create a class with only one mutable field
  2. Wrap the immutables functions.
Here's an example. You've got a copy-on-write list implementation but your binding it to some GUI control that gives you a big headache if you try and point it to a different data source.

Here's your immutable:
  class CopyOnWriteList
{
private readonly IEnumerable items;

CopyOnWriteList Add(item)
{
return new CopyOnWriteList(new List(items, item));
}
}
Now wrap it:
  class WrappedCopyOnWriteList
{
CopyOnWriteList list;

void Add(item)
{
list = list.Add(item)
}
}
There, it couldn't be simpler. So simple in fact I don't know what else to say. Enjoy!

The Singleton Killer

We all hate singletons so here's another useful refactoring pattern: The Singleton Killer.

Here's a common snippet of code we all love to hate:
class Transfer
def funds(from_number, to_number, amount)
from = AccountRepository.instance.get(from_number)
to = AccountRepository.instance.get(to_number)
from.balance -= amount
to.balance += amount
end
end
So how do we kill this beast? Simply follow these idiot proof steps:

Step One: Introduce Field
Stop asking the singleton for it's reference and store your own by creating a field:
class Transfer
@repository = AccountRepository.instance
def funds(from_number, to_number, amount)
from = repository.get(from_number)
to = repository.get(to_number)
...
end
end
Wow: it's starting to look like normal code!

Step Two: Initialize in constructor
Move the initialization to the constructor:
def initialize()
@repository = AccountRepository.instance
end
This is good but wouldn't it be better if the dependancy could be injected?

Step Three: Chain constructor
In languages where dependency injection is useful you will need to chain the constructors:
public Transfer() : this(AccountRepository.instance)
public Transfer(AccountRepository repository)
{
this.repository = repository
}
Now the AccountRepository can be injected which of course means we can mock it out!

Step Four: Extract interface (for statically typed languages)
Except statically languages: they'll need to extract an interface:
public interface IAccountRepository
{
Account Get(string number);
}

public Transfer(IAccountRepository repository) ...
Good: now you can start mocking and testing.

Step Five: Introduce container
If you haven't already got a container then get one (else ensure you a wiring up your dependencies in one place). Then get that to wire up the Transfer object for you:
container.Add(AccountRepository)
container.Add(Transfer)
transfer = container.Get(Transfer)
transfer.funds("YOUACCNUM", "MYACCNUM", 50000)
Step Six: Remove singleton
Once a container is doing all your injection for you that singleton is a waste of space: get rid of him by removing that horrible instance accessor.

Choose your strategies with this refactoring wisely: if your objective is to get a class tested then first repeat steps one-four within the same class until it is clean of all singletons. This is a good exercise in it's own right - even if you're not going to move on to test or remove the singleton completely - as you start to move all the dependancies to the constructor you gain a better picture of the classes collaborators (and the quality of design). On the other hand if your objective is to remove the singleton repeat steps one-three on every usage you can find then finish up with steps four-six. Another technique is to keep pushing the useage of the singleton up through the code so each client then takes on responsibility for passing the singleton down when it creates an instance of the class. Like so:
  Transfer.new(AccountRepository.Instance)
Then repeat steps one-three on the class you've just pushed into, then push the singleton up again up and so on until you can't push it anymore. This can be an interesting exercise in itself as it starts to push out the paths through the code base as you move through the layers and may also give you a clear point where your container needs to be. Be warned though: it can get messy (though strangely satisfying)!

On larger, messier codebases none of these approaches may be realistic in which case opt for the guerilla approach and pick them off as you find them. Though I would encourage trying to at least clean out a whole class using steps one-three even if you won't end up testing it right away. With all your dependancies in one place you'll still have a better picture of the design.

Saturday, 25 October 2008

if(conditional) push.down(to.origin)

Conditionals (ifs, switches) are a plague in many code bases and although there are campaigns to prevent their spread many developers are unclear on how to control these pests. Conditionals are one of the most prevalent, yet tolerated, sources of repetition and bugs. Why? Well let's start with one simple yet common example:

if(thing.is_valid) do
other_thing.do_something_with(thing)
end

This sort of code spreads like a disease because every time the client calls do_something it must ensure it checks for validity. If we look closer at the object in use we find that calling do_something in an invalid state not only requires the same conditional but also throws an error:

def do_something_with(thing)
raise "Thing must be valid" if not thing.is_valid
// do lots of wonderful things with a valid thing
end

The repetition is not only in the client code but in tests:

def calls_other_thing_when_thing_is_valid
mock_thing.expects(:is_valid).returns(true)
mock_other_thing.expects(:do_something).with(mock_thing)
...
end

def does_nothing_when_thing_is_invalid
mock_thing.expects(:is_valid).returns(false)
...
end

The simplest solution to remove the glut of these conditions (in terms of lines of codes, not calls) is to push it down off the client and to the object who knows his state. If we go back to the tests and use BDD we find that we would rather define the interactions as such:

def tells_thing_to_do_something_when_valid
mock_thing.expects(:when_valid).with(block)
end

Thing now takes a block (in ruby), delegate (in C#) or anonymous class (in Java):

thing.when_valid({other_thing.do_something_with(thing)})

def when_valid(&block)
&block.call if valid
end

Now the conditional is controlled by the object responsible for its state: we've removed an Ask and replaced it with a Tell. This is a vast improvement, all the repetition in the clients has gone and the chances of bugs due to accidental calls when in an invalid state are removed.

This presumes that Thing doesn't really do much but chances are it's got lots of behaviour and the chances are that behaviour changes based on being valid or not. Of course all the methods could delegate to its own when_valid method but I bet you also need a when_not_valid and oh boy that code's getting difficult to read. Also, the repetition, in terms of lines of code may be lower but how many times are conditionals executed during run time?

class Thing
def when_valid(&block)
&block.call if valid
end

def other_method
if valid do
// do some stuff
else
// do some different stuff
end
end
end

The conditional can still be pushed further down right to its origin: when Thing changes between a valid and invalid state. This can be achieved by using the Replace Conditional With Polymorphism refactoring to employ the state pattern:

NOTE: I want to keep this example clear for developers of other languages though there are cleverer ways of achieving this in Ruby

class Thing
def validate
valid = // check if valid
@state_behaviour = valid ? Valid.new : Invalid.new
end

def when_valid(&block)
@state_behaviour.when_valid(&block)
end

def other_method
@state_behaviour.other_method
end

class Valid
def when_valid(&block)
&block.call
end

def other_method
// do some stuff
end
end

class Invalid
def when_valid(&block)
// ignore
end

def other_method
// do some different stuff
end
end
end

Now there is only one point where the conditional is called and all of the behaviour for each state (valid or invalid) is in one easy to read place.  Of course, this is just a simple example so just imagine what it would do for more complex solutions (and don't forget: the same can be applied to switches).

Sunday, 13 May 2007

Encapsulating Top Trump objects

Many of the objects we design are like Top Trumps: on first inspection it looks like we should be exposing all their information so we can see it but when you look closer you realize it's 100% about behaviour.

What do I mean? A Top Trump game consists of you looking at your card and choosing what you believe the be the best statistic on your card and challanging your opponent. This leads us to expose the data of our Top Trump object using properties so we can see them clearly. In reality however the Top Trump card should be keeping it's data secret: it is only exposing it's data to you not to your opponent, you merle ask your opponent if your card beats his but you never know what data his card contains.

If we were to model this in an OO world we would probably have a TopTrump class with various comparison methods. We wouldn't want to do the comparisons ourself. As an example we wouldn't do:

public void ChallangeOnSpeed()
{
if(me.CurrentTrump.Speed > opponent.CurrentTrump.Speed)
{
me.TakeTrumpFrom(opponent);
}
else if(me.CurrentTrump.Speed < opponent.CurrentTrump.Speed)
{
me.GiveUpTrumpTo(opponent);
}
else
{
// it's a draw
}
}
Instead we'd have the Trumps make their own desicions:

public void Challange(IStatistic statistic)
{
ChallangeResult challangeResult = myTrump.ChallangeWith(statistic);

if(challangeResult.Equals(Won))
{
TakeTrumpFrom(opponent);
}
else if(challangeResult.Equals(Lost))
{
GiveUpTrumpTo(opponent);
}
else
{
// it's a draw
}
}
So what has this gained us? It is no longer down to the player to compare the information the trumps expose instead the responsibility for comparison is with the trumps themselves. Now the trumps are autonomous in deciding how they should behave: they are encapsulated. "And the point of that was?" To answer that question let's look at the evolution of our model. The first version of our software only supported one type of Trump and that was the Supercars pack. Our players could compare directly by choosing ChallangeOnSpeed etc. but now we've designed a new Marvel Comic Heroes pack which have different categories. We'd have to either add new methods or create new Player classes to handle the new Trump classes and new Game classes to handle the new Player classes. What a load of work! Then what happens when Dinosaurs pack or the Horror pack comes out? Or what if we go global and the speed is worked out in KM/H as well as MPH or dollars as well as sterling? By exposing the data we have overburdened the Player and the Game classes with responsibility causing a maintanance nightmare so now everytime our domain evolves our code breaks.

This is why properties break encapsulation when they expose data directly. When we put the responsibility to compare data on the class which doesn't own it then any change to the class that own's the data has a ripple effect through your whole code breaking Single Responsibility Principle. If on the other hand the object itself is responsible for carrying out the operations on it's data you only make one change and in turn you strengthen the concepts of your domain.

"OK" I hear you say "but you have to expose properties so you can render the data on the user interface". Ah but do you? What if the Trump object told the UI what to display? "Surely that would mean putting UI code into the Trump object and that's just wrong and anyway I need that data to save to the database as well does that mean we also end up with data code in the class that's even worse?" Not if we use the Mediator pattern (hey imagine a Design Patterns Top Trumps!).

Mediator to the rescue
On a side note I'd like to discuss why I said Mediator over Builder. Some people use the Builder pattern (Dave Astels did in his One Expectation Per Test example) which is a construction pattern used to seperate the construction of an object from it's representation. The purpose of the Builder is that at the end you get an object. However when working with a UI you may not have an object as an end product instead you may be just sticking your values into existing objects. The Mediator on the other hand merle acts as an interface which defines the interaction between objects to maintain loose coupling. You could argue that some implementations of Builder are really Mediator with a Factory method (or a combination of both as we shall soon see).

Well let's start by defining our mediator for our Top Trump. For those who have read my blog before you'd know I'm a big fan of Behaviour/Test Driven Development but for the sake of consisnese I'll deal only with the implementations for these examples.

public class TopTrump
{
int speed;

public void Mediate(ITopTrumpMediator mediator)
{
mediator.SetSpeed(speed);
}
}

public interface ITopTrumpMediator
{
void SetSpeed(int speed);
}
Of course you could use a property (what?) for setting the data if you so wished (I think that's perfectly legitamate as it is a behaviour to change the value) however there are good arguments for using a method one of them being overloading (suppose we wanted SetSpeed(string)).

Now when we implement our concrete Mediator we tie it to the view:

public class UiTopTrumpMediator : ITopTrumpMediator
{
private readonly ITopTrumView view;

public UiTopTrumpMediator(ITopTrumView view)
{
this.view = view;
}

public void SetSpeed(int speed)
{
view.SpeedTextBox.Speed = speed.ToString();
}
}
That works nicely and of course you could implement a database Mediator as well using one method regardless of the destination (I love OO don't you?). The only thing is our Mediator is a bit too close to the exact representation of the object. If we were to introduce our new packs we'd have to rewrite our mediator interface and all the classes that consume it. What we need to do is get back to our domain concepts and start dealing in those again:

public interface ITopTrump
{
void Mediate(ITopTrumpMediator mediator);
}

public interface ITopTrumpMediator
{
void AddStatistic(IStatistic);
}

public class SupercarTrump : ITopTrump
{
int speed;
SpeedUnit speedUnit;
 public void Mediate(ITopTrumpMediator mediator)
{
mediator.AddStatistic(new SpeedStatistic(speed, speedUnit));
}
}

public class DinosaursTrump : ITopTrump
{
StrengthStatistic strength;

public void Mediate(ITopTrumpMediator mediator)
{
mediator.AddStatistic(strength);
}
}
Then on IStatistic we'd add a ToString method like so:

public interface IStatistic
{
string ToString();
}

public class SpeedStatistic
{
public string ToString()
{
return String.Format("{0}{1}", speed, speedUnit);
}
}
Of course we could go on and on refining and refactoring - adding muli-lingual support to our mediator etc. - but hopefully you get the picture; by encapsulating the data of the object and placing the stress on it's behaviour we protect it's internal representation from being exposed thus decreasing it's coupling and making it more flexible and stable during change.

Now if I'm honest with you after having all the above revelations there was one scenario I struggled with which I hadn't found any good examples to. Basically everyone talks about displaying data to the UI but never about changing the object from the UI. Changing the data implies breaking encapsulation in someway and if the UI isn't allowed to know about the internal representation how is it supposed to change it? Basically how would our Trump Designer package create new Trump cards and edit existing ones?

Well creation is easy: we'd use the builder pattern and have a concrete implementation of ITopTrumpBuilder for each type of Top Trump card. The UI would then simply engage the ITopTrumpBuilder and pass it's data across in much the same fashion as with the mediator just in reverse. The builder could even tell us if the resulting Trump is valid before we try and get the product.

Remember memento? (not the film the pattern)
But still what about editing an object? There's a pattern called Memento which because of the film is probably the catchiest of all the pattern names but it still is quite a rarity to see it used. That's because Memento's core purpose is for undo behaviour which is very rare on enterprise systems but it is handy for general editing scenarios. Basically Memento is either a nested private class which either holds or is allowed to manipulate the state it's container (the originator) or an internal class which the originator loads and extracts it's values from. Therefore Mementos offer a very nice way of encapsulating edit behaviour if we combine it with Mediator to create a public interface which objects external to the domain can use.

public interface ITopTrumpMemento
{
void UpdateStatistic(IStatistic);
}

public class SupercarTrump : ITopTrump
{
private State state;

private class State
{
internal int Speed;
internal SpeedUnit speedUnit;
}

private class SupercarTrumpMemento : ITopTrumpMemento
{
private State state;

private SupercarTrumpMemento(State state)
{
this.state = state;
}

private State GetState()
{
return state;
}

public void UpdateStatistic(IStatistic statistic)
{
speedStatistic = statistic as SpeedStatistic;
if(speedStatistic != null)
{
state.Speed = speedStatistic.Speed;
}
}
}

public ITopTrumpMemento CreateMemento()
{
return new SupercarTrumpMemento(state);
}

public void Update(ITopTrumpMemento memento)
{
this.state = memento.GetState();
}
}
So there you go: now your UI (or database or webservice) can work with the ITopTrumpMemento interface for editing ITopTrump objects and you can add new TopTrump classes which store their internal data with varying different methods to your hearts content without every breaking any code!

There are advantages to this too numerous to mention; loose coupling is promoted as the UI never gets near the domain, testing is made far easier as you can use mocks of the IMediator, IBuilder and IMemento instead of working with the domain objects direct and also reusability is increased as the mediators take the responsibility away from your presenters.

Tip:
The trick with maintaining your encapsulation as neatly as possible is to try and ensure that your IMediators, IBuilders and IMementos all deal with the concepts of their domain (for example IStatistic) and not the structure of the data (e.g. int speed).

Tuesday, 13 March 2007

Fluent Specification Part 4: Prepacked Questions

I went to my client and demo'd the Bouncer application to him and he was happy so we rolled it out immediately but he did say that the direction of his business had changed recently and we needed to make a few changes.

A week later we met up and he excitedly told me all about how his entertainment service was doing really well but he was not getting the most potential out of his business as he was only open at weekends. What he wanted to do was be open 7 nights a week with different events each night. The problem is that on different events the rules around who to let in will change and my Bouncer isn't flexible enough to handle that at the moment. He really needs me to update the app as soon as to start ramping up his business.

So what we need to do is allow an event class to supply the questions which the bouncer will ask the clubbers. So we need some code like this:
Event tonightsEvent = new Event(new QuestionToAsk(IsClubber.YoungEnough(16), "under sixteens only mate")
.AndNot(IsClubber.WearingFancyDress(), "fancy dress only tonight");
foreach(Clubber clubber in queue.Clubbers)
{
Answer answer = clubber.Ask(tonightsEvent.EntryQuestions);
if(answer.IsFalse) ...
}

To achieve this we have to introduce a new class called a QuestionToAsk. This looks almost identical to the IQuestionSyntax except it has an Ask(T obj) method which returns a IQuestionSyntax instead of an Answer property (this is because the other question is being answered where as this one needs to be given to the clubber). This meant overriding the Ask() method of the clubber to look like this:

public IQuestionSyntax Ask(QuestionToAsk questionToAsk)
{
return questionToAsk.Ask(this);
}

So I implemented the new parts to my framework and checked that all my existing tests and new tests passed and rolled out the Bouncer to the client.

I'm sorry if I rushed the last couple of posts but there should be enough info to get the pattern off the ground. What I like is that I can use the fluent style to make sentances up which are easy to read and apply to objects.

Saturday, 10 March 2007

Fluent Specification Part 3: Giving feedback

There are a few things still left to be done to improve the Fluent Specification.

I’d like to make a couple of points about TDD and iterative development before I go on . Using TDD I have managed to get to a point where I’ve solved one problem at a time and using refactoring I have improved upon my original design and without deviating from my original goal. I have managed to roll out my existing functionality and give real value to my clients. Now I am in a good position to use this proven functionality elsewhere. If I had sat down and said “I’m going to create this great framework for specifications” I would probably have got myself in a complete mess and ended up taking longer to make something unwieldy and over-engineered.

Fluent Specification has been very succesfuly with my customer class so I decide to use it with other objects. I need to employ the power of generics. I don’t think I need to go into detail here so basically I now have the following interfaces:
  • IQuestionSyntax
  • ISpecification

As I was working on another domain I realised that my I realized that I really liked my Fluent Specification with my customer object and so I decided that I should harvest it http://www.martinfowler.com/bliki/HarvestedFramework.html.

The new domain was for a bouncer application which worked through a queue of clubbers and checked if they were allowed in. So I had some nice code which went something like this:

foreach(Clubber clubber in Queue)
{
if(clubber.Ask(IsClubber.OldEnough().AndNot(IsClubber.BreakingDressCode().And(IsClubber.NameDown(guestList))
{
clubber.RefuseEntry();
)
clubber.ComeIn(event);
}

So we rolled out our bouncer application and my client was very impressed. The number of dodgy clubbers getting in went down and everything was good. A few weeks later my client comes back and says he is getting a large number of complaints because my bouncer is just refusing clubbers without telling them why. I bit my tounge about this implementing standard bouncer behaviour as he likes to operate a customer friendly adult evening enterntainment service. So I went back to my code and tried to find a way of making my bouncer give some feedback.

I had to start introducing some new concepts. For a start my Anwser property became a full fledged object with a Feedback property and an IsTrue and IsFalse properties. I then created a IQuestion interface and a standard Question class which wrapped ISpecifications and Feedback (note how I've used whole value for Feedback).

public class Question : IQuestion
{
private readonly ISpecification spec;
private readonly Feedback feedback;

public Question(ISpecification spec, Feedback feedback)
{
this.spec = spec;
this.feedback = feedback;
}

public Answer Ask(T obj)
{
return new Answer(spec.IsSatisfiedBy(obj), feedback);
}
}

I then had to upgraded my Or/AndSpecification classes to become Or/AndCompositeQuestion : IQuestion classes. I then added feedback logic into the composite questions like so:

public class OrCompositeQuestion : IQuestion
{
IQuestion question1;
IQuestion question2;

public OrCompositeQuestion(IQuestion question1, IQuestion question2)
{
this.question1 = question1;
this.question2 = question2;
}

public Answer Ask(T obj)
{
Answer result1 = question1.Ask(obj);
Answer result2 = question2.Ask(obj);

Feedback feedback = string.Empty;

if(!result1.IsTrue)
{
feedback = feedback.Append("or", result1.Feedback);
}

if(!result2.IsTrue)
{
feedback = feedback.Append("or", result2.Feedback);
}

return new Answer(result1.IsTrue result2.IsTrue, feedback);
}
}
I then walked through my code refactoring in my new classes and adding the Feedback paramater to my Ask method. Now I could do this:
Answer answer = clubber.Ask(IsClubber.OldEnough(), "over eighteens only mate")
.AndNot(IsClubber.BreakingDressCode(), "trainers aren't allowed")
.And(IsClubber.NameDown(guestList), "if you're names not down you're not coming in");
if(answer.IsFalse)
{
clubber.Refuse(answer.Feedback);
}
clubber.ComeIn();

I have left alot of code out there but I think you should get the picture. There is a bit of cleaning up needed to do and maybe a little refactoring on the structure of my classes but still I've got something that works, it passes my tests, I can demo it to the client and make sure he's happy with my new enhanced Bouncer application.

Fluent Specification Part 2: Becoming more fluent

Last post we went through combining the two patterns Fluent Interface and Specification to make a Fluent Specification and ended up with something like this:
customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods))
OK this all looks pretty good. Now I can ask my customer any question I like but I can only ask them one at a time so I would still have to do:
customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods)) && customer.Ask(IsCustomer.AbleToAffordGoods(goods)) 
Wouldn't it be better if we could extend our fluent interface to make it more, well, fluent?
customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods)).And(IsCustomer.AbleToAffordGoods(goods))
This starts looking more like predicates now (where you can join logical rules together easily).
To achieve this we need a new object called a Question:
public class CustomerQuestion
{
readonly bool answer;
readonly Customer customer;

public CustomerQuestion(bool answer, Customer customer)
{
this.answer = answer;
this.customer = customer;
}
public CustomerQuestion And(ISpecification spec)
{
return new CustomerQuestion(answer && spec.IsSatisfiedBy(customer), customer);
}
public bool Answer
{
get{return answer;}
}
}
And we need to update our Customer Ask() method to look like this:
public CustomerQuestion Ask(ISpecification spec)
{
return new CustomerQuestion(spec.IsSatisfiedBy(this), this);
}
Now we can link Questions together easily and by simply extending the Question we can add methods for Or, OrNot and AndNot allowing us to make nice little statements like:
customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods)).AndNot(IsCustomer.GivingMeFakeId())
There are a few advantages to the Fluent Specification which I’d just like to go over before wrapping up this post; they are:

  • It is easy to join specifications together.
  • Clients can easily apply specifications to objects.
  • It makes the codes intent clearer.
  • Common specifications can be gathered together in a Factory making a clear API of business rules.
  • Unlike some Fluent Interfaces it doesn’t break Query and Command.

Next post I’d like to go over extending the Fluent Specification even further.

Fluent Specification Part 1: Combining patterns

Two patterns which are really quite nice are Fluent Interface and Specification. Both are fairly simplistic compared to most patterns. Fluent Interface is more of a style where you wire objects together in a walk the dot fashion to make them work like sentances. A common fluent interface is NMock2:
Expect.Once.On(object).Method("Name").With(value).Will(Return.Value(returnValue)) 
Compared to the old non-fluent interface of:
mockObject.ExpectAndReturn("Name", returnValue, value);
At first it looks like more code but as expectations become more complex and to anyone reading the code the fluent interface is a lot clearer and easier to work with.

The specification pattern comes from Eric Evans and is found in detail in his book Domain Driven Design. The idea of the specification pattern is to break your business rules into small self contained, reusable objects called specifications. The specification has an bool IsSatisfiedBy(object) method. The idea is to give some sort of predicate style to OOP languages. So rather than:
if(customer.Age >= goods.MinimumAge)
You replace it with a LegalAgeSpecification which looks like the following:
if(new LegalAgeSpecification(goods).IsSatisfiedBy(customer))
Which again, although may look like more stuff going on once you've got a few of these scattered about your class soon becomes clearer and easier to use. The added bonus is specifications can be reused all over the place: for example for validation, searching collections or within other specifications and they keep all of your business rules in the domain where they belong. What you'll soon discover is you will build up a rich set of business rules in your domain you can call upon at will.

So how about we take this a step further, create some synergy between some patterns (which is undoubtably where patterns get their greatest power) and create a Fluent Specification? The idea behind a Fluent Specification is to make your specifications look more fluent. The above code is rather ugly so why can't we do something like this instead:
if(customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods)))
Isn't that a lot clearer already? The goods object now flows with the sentance of the interface rather than trying to hide its role by sitting in a constructor. Already we have made our intent clearer.

So how would we write something like this? Well there are three main components to this example:

  • A Question (the Ask() method)
  • A specification factory (the IsCustomer singleton)
  • A specification (the OldEnoughToBuyGoods object returned from the factory)

Normally I would do this TDD and set up a test which looks like the following:

Customer customer = new Customer();
customer.Age = 14;
Goods goods = new Alchohol();
Assert.IsFalse(customer.Ask(IsCustomer.OldEnoughToBuyGoods(goods)))

And of course test IsTrue as well but I don't want to make this post 100 pages long so you'll just have to take my word for the TDD. So the first thing to do (TDD style) would be to write a test for the specification itself and test it. So my specification looks like:

public class LegalAgeSpecification
{
readonly Goods goods;
public LegalAgeSpecification(Goods goods)
{
this.goods= goods;
}
public bool IsSatisfiedBy(Customer customer)
{
return customer.Age >= goods.MinimumAge;
}
}

I want to just draw attention to a few things about this specification: I have been very specific about passing the goods object and through rather than making a more generic OlderThanSpecification. The reason is that I may wish to expand this specification in the future to include more business rules as they come up: for example the business rule may say that for certain goods we must check for ID, so the rule may expand to this:

public bool IsSatisfiedBy(Customer customer)
{
if(goods.RequireId)
{
return customer.Id.DateOfBirth.CurrentAge >= goods.MinimumAge
}
return customer.Age >= goods.MinimumAge;
}

Of course you may wish to factor out that rule into a seperate ValidIdForMinimumAgeSpecifcation and call it within this one.
Does this go against YAGNI (You Ain't Gonna Need It)? No: because you are making the object more specific and more flexible by making a very simple design desicion. To have created a more generic OlderThanSpecification is more YAGNI as there is no requirement for that just yet. You may find that as time goes on you will refactor out the rule into a seperate spec but on first pass keep your objects specific to the business rule and inline with the ubiquitous language.
So now we have a specification and its up and running so how do we make this fluent? Well I'm going to rush forward and dump the Factory and the Question out in one go (though I was a little more structured using TDD).

public class Customer
{
...
public bool Ask(ISpecification spec)
{
return spec.IsSatisfiedBy(this);
}
}
public static class IsCustomer
{
public static ISpecification OldEnoughToBuyGoods(Goods goods)
{
return new LegalAgeSpecification(goods);
}
}

During my TDD to achieve my goal of a fluid and flexible interface I needed some refactoring and created an interface for the specification. Now my old specifaction implements the ISpecifcation interface making the Ask() method polymorphic.

Next post I’ll go through making this even more fluent.

About Me

My photo
West Malling, Kent, United Kingdom
I am a ThoughtWorker and general Memeologist living in the UK. I have worked in IT since 2000 on many projects from public facing websites in media and e-commerce to rich-client banking applications and corporate intranets. I am passionate and committed to making IT a better world.