Monday, September 29, 2008

Is NDA in conflict with YAGNI?

I got a question on my previous post (The No Dependency Architecture (NDA)) if NDA is not in conflict with YAGNI, and when I was writing the response it became more or less an actual post, so there you go :)

Explaining the thought behind the No Dependency Architecture (NDA) in combination with YAGNI in one sentence would be something like this: “You anticipate change at a technical level, not at a functional level”.

I believe that the “You Ain’t Gonna Need It” (YAGNI) principle does not imply that writing software accordingly to the SOLID principles is bad practice. When you are following these principles (and there are others that are good to follow too) then you are writing software that assumes change, right? I believe that YAGNI is more targeted to functional overhead.

I.e. using a IoC container to fulfill the Dependency Inversion Principle (DIP) is not in conflict with YAGNI because that is at a technical level, but when you are writing extra code for no other reason than that you assume the object might be used in a certain other way also, then you are violating the YAGNI principle because then you are creating additional functionality that is not needed.

From Wikipedia ( http://en.wikipedia.org/wiki/You_Ain't_Gonna_Need_It) YAGNI, short for 'You Ain't Gonna Need It', suggests to programmers that they should not add functionality until it is necessary

So I would recommend using the various SOLID principles when writing your software assuming things will change because that is just good practice. Change is a fact, we just don’t know what will change, but by conforming to SOLID we can handle these future changes without too much headache.

As to using an Event Driven Architecture, I am surely not saying each object should only interact using events, that would not make much sense, but most (larger) systems will be build up using multiple sub systems. Having these sub systems communicate via events is a very good way to isolate them from each other. Then it is unknown to each sub system who they are really talking to (i.e. dispatching the events to). In fact it is a 1 to n relationship where the dispatched event might have no, one or many subscribers.

To make the actual handling of subscribing and publishing easier you could use a service bus that deal with that for you. This will also make the system easier adaptable to change. You can also specify that the event can be handled by any instance of the same subscriber enabling load balancing.

“Don’t call us, we call you” ( http://en.wikipedia.org/wiki/Hollywood_Principle); is the basis of an Event Driven Architecture, and this is very true, because no system is waiting on an answer from another system. They fire events and they act on events, it is merely coincidence if these events have anything to do with each other.

So I would also recommend using an Event Driven Architecture (EDA) straight from the beginning, perhaps not using a service bus from the start, but just using EDA will make refactoring to use one at a later stage a lot easier.

2 comments:

Anonymous said...

Good answer and I hear you :-) I however still think that YAGNI also apply to code in some extent. Meaning some developers have a tendency to over design/architect solutions using too many principles.

Saying that I also think that generally most solutions would benefit from NDA, and it should be applied more often than it is, but there are exceptions.

In some cases it makes sense to build your solutions or part of your solution with fast straight forward tight couplings. If your application is evolving into something more than just a simple app or your part of the system is being changed frequently and are getting more complex, redesign and use NDA. Also, don't be afraid to throw away source code.

At least that's they way I feel about it at them moment :-) But I'm known to change my opinions ;-)

Mark Nijhof said...

Changing your opinion / mind indicates a learning process, I hope I'll never get stuck ;)

You are true that it is not a solution for all cases, nothing ever is, but I don't see why you wouldn't use for example Interfaces instead of tightly couple the application by using 'real' objects.

Using Interfaces and providing the objects based on that; whether or not you are using an IoC, is in my eyes a must. It just means I am not using an specific object but merely an implementation of this specific Interface. Then when the application grows and you want to go move to a more full blown NDA it is also easier to refactor it into that, but that is not the reason I want to use it in the first place. The reason is that it makes my code assume change and it doesn’t take any more effort (especially when using ReSharper). I can’t think of this as being YAGNI, but yes using a full blown IoC in a 100 line project that you’ll never touch again probably is :)