Evan has an OK post here, detailing the intrisics of Object Composition and Inheritance. He is very right in the way he is doing stuff, but while I was reading, something was bothering me as well. The thing that bothered me was that the code I am writing in the projects I am doing right now does not look a lot like what he is doing - and I think that I am following the OOP principles just as well as he is. So what is the difference? Actually it is that I am not "paying the Interface tax".
When I had my Advanced OOP course at ITU we really got down and dirty with using interfaces and loosely coupling everything everywhere in the programs, and for a while I followed that road in my stuff as well. But then I began to bug me that for every odd class there was an interface mirroring the methods on that class. Every time I needed new functionality in that class, I off course duly changed the interface. The great thing here is that the only class ever implementing the interface now, and propably forever, was that class that caused the interface in the first place. I call that paying the Interface tax, and in my eye it is a bad case of YAGNI.
I am not saying that interfaces are bad. They are good - for the right occasions. If you find yourself making interfaces for data entity classes, you are probably getting taxed badly. I usually only get to the point of using interfaces when making "framework stuff". Things I know will be used over and over in different projects. In an application, good old inheritance will more often be what I am after. It can save me a lot if implementation by inheriting functionality and save me the hassle of having YAGNI interfaces only being used by one class hierarchy at a time. And you can always refactor into an interface when the need arises.
So before signing up for the interface tax, remember that simplicity is King.
PS. Have you noticed the great TLA for todays topic. *DUCKING*
3 comments:
I'm coming around the other way. I used to find the interface tax quite costly, adding new methods to my interface first before changing the only class that implemented the interface. However, as I make more use of unit tests (and TDD) I find that writing the interfaces up front is great for testing the code I've written so far without the need for all the other implementation classes to exist yet.
That is somewhat different from what I do. I use TDD and unit testing to fill up the actual implementation line by line. I never write a line of code without having a test that makes that code line nessecary. When writing tests for interfaces I only write very general tests that all implementations must pass, and then I write specific tests for the actual implementations.
I totally agree. From my experience, an additional interface will be mostly redundant and will only burden the developer by introducing a shadow entity. Moreover, there is danger that you won't be able to change the interface anymore, after you've shipped it.
Post a Comment