Abstractions...  mmmm... so sweet

...a post from Ayende on abstractions, and specifically a mention of the logging "abstraction" in Castle... it's an interesting thing, for the Seismic product I worked logging (via the same abstraction) into a product a year or more ago...  in the end we needed the ability to log contextual information (basically exposing features already existing in log4net at the time, but not available via the Castle ILogger interface) and so I ended up creating a new interface that was a superset of the existing abstraction, IExtendedLogger...

here's the devil... looks simple...

public interface IExtendedLogger : ILogger { void AddProperty(string key, object value); void RemoveProperty(string key); }

However... because we're being a good little abstraction "whore" we end up with a few more classes to support this new interface, and make the user experience more pleasurable:

Though I was reasonably pleased with the end result a year ago, that was probably a couple of hours work + some more time tweaking (once you include the time to code up that test fixtures) that would've been better spent building additional functionality into the product.

I have to admit the lure of a needless abstraction is ever present to me... I enjoy halving a class into an abstract and concrete implementation, and then extracting an interface is like the candy coating... prefixing the concrete implementation with "Default" makes it even seem like you've all but got people lining up to create their own versions!  Wow, isn't it powerful, flexible.. and all sorts of other words ending in "ul" or "ile".

....But in the end, needless is needless - and I haven't needed the flexibility gained from this abstraction so far... after a year... a whole year, that's pretty much like never... sure I had grand plans, but they never did come to fruition... and grand plans don't keep me fed - YAGNI strikes again.

About the only thing I find the needless abstractions do is in clarifying my thinking on what I do and don't need, or more importantly what I do and don't want people to do with my code.... it let's me define just what I want my "pit of success" behavior to be, albeit not the implementation... Perhaps some of this stuff is better reserved for throw away prototypes then production code.

I think the best book I've found for discouraging this "80's guitar solo" of abstraction..um...ism is the Framework Design Guidelines... Though these abstractions do make it easy for me to maintain and grow my code (and the orthogonality of the design is generally good) it comes at the price of other people having difficulty learning my API through experimentation, and I fail to create a progressive framework... which after reading the aforementioned book, is something we all wan't to do.

I guess the final question is, do you reverse an abstraction that isn't required after such a long time...?  Or do you just avoid making the same mistake twice and live with the abstraction, assuming it's not hurting too many people - Is it worth lumping it with the rest of the "broken windows" in a project, or is that a little too brash?

Written on October 17, 2006