Abstraction For The Sake Of Abstraction? Why Add Unneeded Complexity?

Leave it to Max Pool from Codesqueeze to introduce us to the concept of Premature Abstraction.  And let’s face it, we are all guilty of it sometimes.  Back when I started working with IOP and Spring we had abstraction crammed down our throats.  EVERYTHING was an interface, and we were told to always code to interfaces rather than concrete classes. 

While this makes for some very efficient code, it also makes for some very complex code.  Max sums it up nicely with a quote from Peter Drucker,

There is nothing so useless as doing efficiently that which should not be done at all.

Don’t get me wrong.  I love abstraction, and I employ it on a regular basis when developing software.  But developing an abstract layer on top of a single concrete implementation because you “might” reuse the abstract code someday is in violation of the YAGNIprinciple.  The main idea behind YAGNI is “If you need it, you can put it in later. If you don’t need it, you won’t have to do the work at all.” 

If you follow any of the IOP or dependency injection tutorials out there you will notice that they almost always encourage you to create an interface, and then use dependency injection to inject a concrete implementation that interface into the using class.  This does a great job of decoupling your code, and you can easily switch between concrete implementations by simple modifying a config file.  But the problem arises when you only have one concrete implementation, or the code is naturally coupled.  Now we have an overly complex model representing a fairly simple implementation. 

Instead adding complexity without any benefit, code to the concrete implantation itself.  Sure, you “might” need to create abstraction out of a class at some point to avoid repeating code.  But until you actually need it, don’t do it.  Just say No to abstraction purely for the sake of abstraction…

Comments

Returning visitor? Please login or register.

Isn’t that what unit tests are for - to ensure your abstraction doesn’t go to waste because it’s being used by testing with mock objects?

Presumably, you’re always gonna need it, because *everything* gets unit tested, and the more decoupled a unit test, the better a *unit* test it is.

scott Posted on: May 22, 2009 at 03:19 PM

yup, there’s a real cost to abstraction that overzealous developers always seem to forget or ignore.  just google for leaky abstraction and “tension transparency abstraction” for some more insightful reading.

tinou Posted on: May 22, 2009 at 03:43 PM

When he says “IOP”, does he really mean “IoC”?

Mike Heath Posted on: May 22, 2009 at 03:52 PM

IOP - Inversion of Poop.

Theo Posted on: May 22, 2009 at 05:16 PM

The point of interfaces is, typically, unit testing. And if you use a top-down approach you’ll start with a lot of stubs. It’s far easier to make these implementations of an interface at the beginning than it is to change it later on.

Cletus Posted on: May 22, 2009 at 09:00 PM

RE: Mike Heath

Yes, I meant to type IoC, not IOP. :)  LOL, that’s what I get for not proof reading my blog.

(I guess I could change it, but that wouldn’t be nearly as fun.  If you can’t laugh at your own mistakes…)

Paul Bourdeaux Posted on: May 22, 2009 at 09:19 PM

Scott and Cletus,

Thank both of you for your comments.  You are correct in saying that abstraction makes it easier to decouple the unit tests.  Whether or not that makes it “better”, well, that might be up for a little debate. 

As far as it being easier to make interfaces in the beginning as opposed to later on, I respectfully disagree.  Any decent IDE can pull an abstraction out of a concrete class and refactor all dependencies in a matter of seconds.

Don’t get me wrong - there is certainly a need for abstraction.  I am not anti-abstraction by any means.  But I also realize that it is not a golden hammer that should be applied to every class regardless of need.

Paul Bourdeaux Posted on: May 22, 2009 at 09:30 PM

wfzenafy  pehngbdy  ccaooxna http://cmofrhwq.com klnngymy jbpxxeyu

zhbbpftb Posted on: May 23, 2009 at 12:41 AM

The issue of coding to interface for mocking during testing is a subject that should be dealt in more depth.  Should we be designing our code so that it can be testing, even if this means that the code is more complex (and likely to require more testing)?

If we are designing interfaces and coding to them, and a third party creates an extension by implementing the interface are we obligated to not break the contract?  Is there not a way to define what is and what is not API?

Dennis Sellinger Posted on: May 23, 2009 at 03:29 AM

Indeed. These days excess use of abstraction is rampant.
And testability is really an empty concept. With the proper tool, a Java developer can now write unit tests for any kind of code.
(I was faced with this issue of how to isolate code under test from dependencies in late 2005, and there was no solution then; so, I created the JMockit tool. Today there are others too.)

I did not understand what you meant by “makes for some very efficient code”, though. Wouldn’t the opposite be true (not that it really makes a difference to use interfaces or not, performance wise)?

Rogério Liesenfeld Posted on: May 23, 2009 at 11:57 AM

Leave A Comment

Please help us stop spam by answering the question below: