Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, 18 March 2008

Polymonoism (AKA the legend of cross platform .NET)

After using IntelliJ for the last nine months or so I have realised how much Visual Studio sucks (even with Resharper).  The problem I have with VS is the IDE seems to be focused on everything but writing code and I feel there is only ten percent of it I use and that only does ten percent of what I can do with IntelliJ.  I, like many others, really wish there was an IntelliJ plugin for .NET (in particular C#) or even a whole IntelliC, however the news on the street is despite JetBrains hinting rather explicitly that such a thing was in the pipe line they've shelved the idea (BOOO).

I can't blame JetBrains for wanting to focus their efforts on Resharper: MS developers, as a herd, generally keep to the MS straight and narrow and fear wandering from the vendor's path of least wisdom.  It makes no commercial sence to develop an alternative IDE from Visual Studio when most MS devs won't even bother to look beyond the MS brochure.  As a plugin Resharper is going to hit a bigger market.

This is a shame and a loss for choice: the Java community has healthy competition with its IDEs and plenty of innovation with it but, Borland aside, this culture doesn't exist in the mainstream MS world (hence why Visual Studio's 'refactoring' and 'testing' features are a joke). 

The other issue is that Visual Studio only runs on one platform (Windows) for one vendor (MS funnily enough); from the ground up most Java IDEs support multiple platforms and multiple vendors of the JDK and compilers.  Why is this of any relevance for .NET - who would want to develop it on anything else when it only runs on Windows anyway?  Firstly I don't want to develop on Windows: I find it an awful OS for doing development on and I am far more productive on Linux or OSX (like many I have a preference for a different OS which happens not to be Windows: why should that even be a statement?), secondly I don't necessarily want to run my .NET applications on Windows: after the luxury of working with true multi platform languages such as Java and Ruby I find it really frustrating to have to ditch everything positive about working cross-platform (and that means working on Windows too) and be shoved into a corner where my choice is simply XP or one of the 26 variations of Vista. 

Even though I may not express a preference for working on Windows or with Visual Studio but there are many things about .NET I really like: there are things about the cleanliness of the language and the SDK which trumps Java (generics anyone?).  The real advantage Java has over .NET is the community around it and the way Sun has left people free to contribute to it, there is far more innovation coming from the Java community than from the .NET one (hell, the .NET community is just trying to port as many Java projects as quickly as it can).  However the .NET community is growing (especially with the ALT.NET movement) and it isn't to hard to wriggle out of the MS straight jacket.  All in all there's a real feeling of excitement around .NET at the moment despite MS's attempts to lump as many bad practices into it as they can.  As a result .NET is a serious contender to Java except it falls flat on its face when it comes to cross platform support.

Well there may be some hope out there: mono is coming along nicely (with almost full 2.0 compatibility) and comes as part of Gnome (so for Linux it's already there) and there is a version for OSX.  With a bit of support and real world proof mono has the potential to become a real Java killer. 

The problem is you're not going to be able to compile to mono in Visual Studio and even if you could you can still only run VS on Windows solving only half the problem.  The other problem is Mono IDEs suck: monodevelop, a sterling effort, is like going back in time 15 years.  SharpDevelop (from which monodevelop was originally forked) would be cool but again it only runs on Windows (booooo to you icsharp).  

A bit of research and I stumbled across a little IDE from Omniture call X-Develop.  Not only does it run on Windows, OSX and Linux but it can handle C#, J#, Visual Basic and Java compiling to whatever framework you choose including mono.  The word on the blogoshpere is that X-Develop is a usable, productive UI and despite not being as feature rich as IntelliJ (it's refactoring support is weaker) or Visual Studio (UI designers) is a slick, quick, lightweight, cross platform IDE, which includes all the essentials including basic refactoring (one up on VS), error highlighting (another up on VS) , debugging etc.  The good news for fans of other IDEs is that you can choose to map keybingins from Visual Studio, IntelliJ, Eclipse and others.

The downside is you have to pay for it and at $499 per license it isn't the sort of thing you'd buy on a whim.  Naturally I'd prefer it to be open source but I'm going to be realistic that people have to make money though a cut down OS version without the designers etc. for free may be a wise move to get people hooked.  Omniture seem to be giving a serious proposition that no other vendor can match in terms of true cross platform, cross framework development and that is a fantastic thing.

The problem Ominiture are going to have is appealing to the Java and Linux community who do have a preference for free software.  The problem mono has is that without a decent cross platform IDE it's not going to gain serious ground.  I think both sides need to reach out and touch each other to ensure mono gets the real-estate it deserves.  I for one would be seriously excited about developing true cross platform applications in C# on my Mac or Ubuntu.  Hopefully it may be a future arriving quite soon and not just another broken pipe dream.

Thursday, 2 August 2007

Seperating the Men from the Morts

I'm a bit slow on the uptake here (maybe I'm too busy to be a true alpha geek) but if you're one of those .NET developers who've always felt a little bit uncomfortable sitting in the MS Fanboy Hummer on the way to the latest .NET launch (and secretly was wishing you were at RailsConf) and because every time you mentioned test first, agile, a new OS project, regret that a Java library wasn't in .NET - or god forbid you actually deployed open source non-MS certified libraries on a production machine! - you got funny looks, then maybe you are an ALT.NETer and never knew it.

The opposite is MORT.NET: those old VB6ers or VisualC++ers who just can't shake the habit of databound controls with a business layer of static methods which shuttle anemic data objects to and from the database and UI, and tests by creating a test app of datagrids and command buttons. The MORT.NETer is a drag-and-drop all star who wouldn't have known what AJAX was until MS released ATLAS (but are slightly cautious as it's FREE) and believe NHibernate is pure evil because it doesn't use stored procedures.

Join the movement comrades: if you're the kind of developer that's prepared to try something because it's cool rather than asking if it is MS certified you're already there!

Tuesday, 17 July 2007

Loopy loops

Encapsulation and information hiding tells us that we encapsulate an objects internal data structure and expose methods, a client can see all the methods but none of the data. Tell, don't Ask extends this to say we should always tell an object to do something, not ask it for some information and then do something for it. The Law of Demeter helps to clarify this by telling us that we should avoid invoking methods of a member object returned by another method. By employing Demeter we avoid "train-wreck"s e.g. a.B.C.DoSomething().

I have seen - and written - a lot of code that does this:

foreach(Object obj in myObject.Objects)
{
obj.DoSomething();
}
But doesn't this break the three rules? First we are exposing the objects internal structure (the fact that myObject has a collection of Objects inside it). Secondly we break Demeter in three ways by:
  1. invoking the GetEnumerator (in C#) method of IEnumerable which was returned by myObject (via Objects)
  2. invoking the MoveNext (which incidently breaks Command-Query seperation) and Current methods of IEnumerator (in C#) which was returned by IEnumerable which was returned by myObject
  3. invoking the DoSomething() method of obj which was returned by the Current method of IEnumerator which was returned by IEnumerable which was returned by myObject (see why it's called a train wreck?)
Lastly we break "Tell, Don't Ask" by asking all the above objects (three in total: myObject, IEnumerable, IEnumerator) in the collection for something and then doing something to obj.

Looping arrays and collections is very common and in most programs exposing the collection is the norm. But what happens when you need to change the way the collection works? What if you decide to replace your objects array with a HashTable or a Set? Thankfully most OOP languages gives you some sort of iterator so, in C# for example, you can just expose IEnumerator and you might be alright. But this still breaks the three rules and what do you do if your underlying data structure doesn't have an IEnumerable? What if you're dealing with some legacy COM+ object and you have revert back to the old for or while? Or even worse, the data structure doesn't even seem to have a simple structure (not so uncommon)? Just exposing an enumerator isn't so easy but we still work around it by doing something like this:

IEnumerator Objects
{
IList list;
for(int i = 0; i < comObject.Count; i++)
{
list.Add(comObject[i]);
}

return list.GetEnumerator();
}
And then in the client we have:

foreach(Object obj in myObject.Objects)
{
// here we go again!
}
Hang on a second: we loop so we can loop? Doesn't that sound a bit strange? To make matters worse we seem to do this as well:

void SaveEverything()
{
foreach(Object obj in myObject.Objects)
{
database.Save(obj);
}
}

... Somewhere else in the program ...

void DisplayEverything()
{
foreach(Object obj in myObject.Objects)
{
ui.Display(obj);
}
}

... Again somewhere else ...

void SendEmail()
{
foreach(Object obj in myObject.Objects)
{
email.Send(obj);
}
}
How many times do you want to write that damn loop? So what's the alternative? To implement the three rules: hide the collection and stop exposing it and then tell the myObject to loop it for you. Quite simply:

public class MyObject
{
void Loop(IReceiver receiver)
{
foreach(Object obj in objects)
{
receiver.Recieve(obj);
}
}
}
All you need to do is pass your receiver to MyObject and it will do all the work for you:

myObject.Loop(databaseSaver);

public class DatabaseSaver : IReceiver
{
void Receive(Object obj)
{
database.Save(obj);
}
}
Or if you prefer you can use delegates and anonoymous methods:

myObject().Loop(delegate(Object obj) { database.Save(obj); });

public delegate void LoopDelegate(Object obj);

public class MyObject
{
public void Loop(LoopDelegate loopDelegate)
{
foreach(Object obj in objects)
{
loopDelegate(obj);
}
}
}


Now if you need to change the objects internal data structure of the way you iterate it (for performance reasons etc.) you can do so with ease and without breaking any of your clients.

Although with simple loops it all looks straightforward enough, it is with more complex structures that you gain a real advantage. In a parent child structure for example you may find a loop such as this:

foreach(Parent parent in foo.Parents)
{
foreach(Child child in foo.Children)
{
// do something
}
}
Writing this loop all over the place can be fairly cumbersome, and what if you don't want to expose the structure in this way? By using the pattern above you have more control over the semantics of the object. For example you could present the list flat and merle passes each object across as above (and thus loosing nested loops all over your code) or you could expose some structure:

public interface ParentReceiver
{
ChildReceiver CreateChildReceiver();
void ReceiveParent(Parent, ChildReceiver);
}

public interface ChildReceiver
{
void ReceiveParent(ParentReceiver);
}

public class Parents
{
public void Loop(ParentReceiver receiver)
{
foreach(Parent parent in parents)
{
ChildReceiver childReceiver = receiver.CreateChildReceiver();
parent.Loop(childReceiver);
receiver.ReceiveParent(parent, childReceiver);
}
}
}

public class Parent
{
public void Loop(ChildReceiver receiver)
{
for(int i = 0; i < children.count; i++)
{
// don't pass any illegitimate children!
if(children[i].IsNotIllegitimate)
{
receiver.Receive(children[i]);
}
}
}
}

As you can see by following the three rules and telling the object what to do, and only the immediate object what to do, we can not only express the structure of the objects better and force clients to work with that structure, we also loosen the object couplings.

Tip:
For those pre .NET 2.0 people out there, or those who use languages that don't have generics, by using the above pattern you can strongly type your objects even if you can't strongly type the internal collections.

Friday, 27 April 2007

Being more Fluent with Equals

A lot of .NET developers don't realise that there is a difference between the == operator and the Equals method. Even fewer developers realise there is a difference between the == operator and the == operator. Confused? That's because == will behave differently depending on whether you apply it to a reference type or a value type. More confusingly some .NET classes override == and will behave differently again. To explain MS made this attempt:
For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings.
Except that's not entirey true. The == operator on string only works if they are both strings. Confused even more? Then read this post from the C# FAQ.

So are you clear now? If not then MS sums it up quite nicely in their Guildelines for overloading:
To check for reference equality, use ReferenceEquals. To check for value equality, use Equals or Equals.
So why don't developers have it drummed into them to follow the above advice and just dump ==? Because they believe that == is easier to read. Let's think about it for a moment. How is it easier to read? Using == risks making buggy code and goes against every rule about intention revealing interfaces and maintaining encapsulation. How the hell do you know what the developer intended when she did x == y? Were they checking for value equality or reference equality? Or had they overloaded == to always do value equality (as string does)? Basically you don't know (breaking intent) and you'd have to open up the class to see (breaking encapsulation) and still you won't know for sure. Then of course there is just plain = now did they mean to do that or did they just miss the second =? So == is definitely not easier to read from an intent or encapsulation point of view.

So they must mean that == is better style. This I believe is flawed because sometimes you end up doing a bit of == here and a bit of Equals there and what's more all objects have Equals but structs do not have ==. So having a style which prefers == except when == doesn't do the same thing as Equals (or == doesn't even exist) throws all consistency and style out of the window and you end up with a style guide that says "use == except when or when or when" rather than just placing a total ban on ==.

Then it must just be that == looks better. I think this is just habit. Lets take the following lines:
if(x == y)
{
// do something
}
if(x = y)
{
// do something
}
if(x.Equals(y))
{
// do something
}
If you took a group of people who knew little about development (or C# for that matter) and ask them what each line means I can guarantee everyone of them will always get the last line right (they'd probably think that the double equals meant equals twice and that would confuse them on the single one). The Equals method is the most explicit and clear and readable of all of them (it actually reads as x equals y). To further prove my point grab your same person and ask them what this means:
if(x)
{
// do something
}
if(!x)
{
// do something
}
Then ask them what this means:
if(x.Equals(true))
{
// do something
}
if(x.Equals(false))
{
// do something
}
Those second examples look far clearer and you'd be an idiot to not know what the intent was. What's more they make their own mini fluent interfaces. Also you eliminate all those "oh there's a bang at the beginning" bugs. However I think it is fair to say that x.Equals(true) is a bit overkill though I do find that x.Equals(false) is somewhat clearer than the using the logical negation operator.

So after knowing that technically it's the right thing to do, that it's better for showing intent, that it is more consistent, that is reduces risk of bugs and everything else, if you still need convincing because you still think that == looks better then justify it by saying you're using a fluent interface.

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.