Ben Northrop


Decisions and software development


Does Programming to Interfaces Buy Us Anything?


(24 comments)
May 28th 2008


I need to butt heads with conventional coding wisdom for a minute. We've all heard that it's good to program to interfaces and not implementations, but I'd like to argue that in a lot of cases I see nowadays, it actually buys us very little. In fact, it often just causes code bloat and developer frustration. There, I said it!

Here's the picture I see so often:

Note that implementations only depend on interfaces, and the actual implementation that realizes the interface is injected via some IOC container (e.g. Spring) or found via some Service Locator. For example, the CustomerAction uses a CustomerManager, but which CustomerManager implementation it doesn't have to know or care about.

This is all done in the name of reduced coupling, since we all know that loosely coupled systems are more maintainable and extensible than tightly coupled systems. But is loose coupling always good?

The benefits vs. the reality of programming to interfaces

Well, indeed there are some benefits to programming to interfaces and not implementations, but in many cases I think they just don't apply. Here are some of the touted benefits, and the reality that negates them.

Benefit: Coding to an interface allows you to easily substitute implementations whenever the mood (or the requirements!) strike you. If for some reason you need to swap CustomerManagerImpl with BigCustomerManagerImpl, you'd be sitting pretty. You'd just change the Service Locator or IOC config file/class to use BigCustomerManagerImpl instead of CustomerManagerImpl, and never have to bother updating any client code. Voila! With one class and one config file changed we have all new behavior.

Reality: Unless you have a reasonable expectation that you'll need multiple implementations, this benefit really holds no water. Essentially, why decouple two things from each other if it's likely that they'll always be coupled? For DAO and Manager-type classes, this is especially true. Sure someone will argue "if we program to DAO interfaces rather than implementations, when we switch from Oracle to DB2 we'll never need to touch our business logic!". The question to ask, however, is, "is this a reasonable possibility"? In most enterprise environments, the probability of swapping databases so low that it's irrational to spend any time or effort attending to it (see The Architect's Dilemma). Ditto for business manager classes. Really, what other types of CustomerManager implementations could we imagine? In the end, I'd argue that it's usually pretty clear when multiple implementations will be possible - and in business applications this is most often in the domain model (e.g. Account has children: SavingsAccount and CheckingAccount), business Strategy or algorithm-type classes, or frameworks and other infrastructural components.

Benefit: Creating stub classes (e.g. StubCustomerManagerImpl) allows me to better isolate the system under test, enabling better testability. For example, if I was unit testing the CustomerManagerImpl, I could create and inject a StubCustomerDAOImpl so that I'm not testing multiple things.

Reality: In practice, this benefit is pretty negligible since newer mock-object frameworks (e.g. EasyMock, JMock, etc.) can create stubs and mocks for classes without interfaces.

Benefit: Some purists might argue that creating a CustomerManager interface is cleaner and more maintainable/readable - all the methods are right there in the interface, with none of the obfuscating implementation details.

Reality: With modern IDEs, I find this argument tenuous at best - if I want to know the public methods, I'll probably rather just look in Eclipse's Outline view.

Benefit: Coding to interfaces enables integration with other subsystems and modules. Clients which call your CustomerManager remotely, for example, need only include (i.e. in a dependent JAR) the interface, and not the implementation. Again, this allows your implementation to change without having to rebuild and redeploy all the clients (assuming the contract hasn't changed, of course).

Reality: No counter-argument, but this obviously only pertains to the API for your system.

Even further, there are some very real (although admittedly relatively minor) costs to coding to interfaces as well: an increase in the amount of code we have to maintain, it's harder for developers to step through code (e.g. F3 in Eclipse won't work!), and there is an additional step for adding or modifying a method in a class (i.e. change it first in the interface and then the impl. ugh.).

Conclusion

In the end, I'm not saying that programming to interfaces and not implementations isn't a good thing, just that it's a good thing less often than we think - in other words, it can't just be dogmatically applied. Again, unless there's a reasonable expectation that another implementation underneath the interface will be needed, I say don't bother.

Do you agree? Disagree? Am I missing something? (I'm sure I am!). Let me know what you think.

Resources

I believe that software development is fundamentally about making decisions, and so this is what I write about (mostly). I'm a Distinguished Technical Consultant for Summa and have two degrees from Carnegie Mellon University, most recently one in philosophy (thesis here). I live in Pittsburgh, PA with my wife, 3 energetic boys, and dog. Subscribe here or write me at ben at summa-tech dot com.

Got a Comment?


Sign up to hear about the next post!

If you liked this article and want to hear about the next one, enter your email below. I don't spam - you'll only receive an email when there's a new post (which is about once a month, tops). It's all low-key, straight from me.

Comments (24)

May 29, 2008
To me it's all about abstractions. Interfaces allow you to create abstractions over the domain and model a clean OO design. By programming to interfaces we program to abstractions. The rest is implementation.
May 30, 2008
As the warpedJavaGuy said it is about abstractions.
You mustn't let the java interface be the substitute for the Interface Erich Gamma mentioned. There are a lot of other programming languages that doesn't have such a construct.
And yes your arguments are mostly valid when you look at the implementation level (in Java that is). although keep in mind that using concrete classes and proxying them can lead to memory leaks when using tools such as cglib or asm.
May 30, 2008
I have something to say here (http://seeingfuture.blogspot.com/2008/05/programming-to-interfaces-buy-me.html)
Sakuraba
May 30, 2008
Your example-diagram does show the true value of interfaces. I agree that this interface-per-DAO- hing is pretty useless in many cases. But that is not the most compelling case for usage of interfaces.

You need to have an example where an interface acts more like a contract between different logical aspects of code.

The easiest example that comes to my mind is the Iterable interface( http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Iterable.html ). Because e.g. the new foreach loop in java 5 can take any Iterable, you can implement Iterable in your client code and therefore making it possible to use your client class in foreach loops.

Had foreach been written towards a specific implemention - say any Collection class for example - this wonderful scenario would not be possible. Iterable provides a contract in this place, it tells you "if you implement this interface, I can provide functionality for you without knowing any of your details".


THAT IS what interfaces buy you, if they are used in the correct place. Not every DAO needs one though, matter of fact if I ever see a IUserDAO or something like that, I will quit software engineering.

Sakuraba
May 30, 2008
Damn.. the first sentence should have been

"Your example-diagram does NOT show the true value of interfaces."
May 30, 2008
While I don't hold back on my criticism of Java, I do think it succeeded in bringing contractual development into the mainstream and generally with a lot of bennefits.

Of course, possibly that hindered other things, like language evolution (look at how much more work we need to do in Java where patterns via interfaces are preferred over practical language features like in C#).
Anthony
May 30, 2008
Use of interfaces with IoC can be of great benefit when the requirements clearly state the need to be able to swap out different classes. As an example, building multiple reports with collections of parameters ranging from layout to ranges. Doing it all without interfaces results in a large amount of glue code that is simply nasty to look at. On the other hand, with interfaces and IoC each class now becomes a small pluggable component that swaps in and out with a quick edit of a text file.

I'm not sure I like the idea of relying on my IDE to provide me information. It's a slippery slope that leads developers to become dependent on the IDE and eventually become useless without it. The thought of C++ developers who can't perform simple actions without a Vistual Studio wizard comes to mind.

However, I also don't believe interface files solves the problem either as you are still forced to munge around through files and directories in search of your target. I think in the end it really comes down to having good documentation both in and out of the code (ie: javadoc and supplemental documentation that tells the newb where to start). With good documentation and a clear high-level overview of the code or library, I don't know to what extent an interface can provide additional information.

I suppose it really comes down to scope and requirements. Some people would argue that you should always code to the interface. I argue that doing so may limit your ability to use the extending class. I'd write more on the issue but I just saw the time and realized I'm late for work!
May 30, 2008
Set proprierties type as interfaces not as implemented classes.
For example set
private Collection strings instead of ArrayList. It would skirt future refactories if you'll inject different implementations than the initial development.
I keep in mind the say "write once" so when i write code, i write straight naked object, unless it appears a sort of generalization between classes, then gather them toghether and generalize within superclass, abstractclass or interface refactoring as much as possibile, if necessary.
nkijak
May 30, 2008
IMHO it's not about expectations since you can't try to expect everything or you'll tear your hair out. It's about leaving something where you can tweak as much stuff as possible with as little impact as possible in the future. This could be days, months or years (although with days maybe you're just doing it wrong from the start)
I just had a project where I had to replace the FTP implementation because it was very old code and it didn't meet all the requirements for the new FTP server. I was hoping that it would be a simple replacement but since there was no interface (and why would you think to use one on something as old and developed as FTP) all the code was tied to this implementation. It required many, many changes and partial rewrites to switch over. I assure you we now have a FTP package that uses a common interface for all future work.
So my point is that you never know what you'll need to replace. Yes, when you have one implementation of the interface now it seems like a waste but you just might need that interface when something unexpected comes up.
bobmanc
May 30, 2008
I don't think Ben is saying that interfaces are bad. They are obviously very useful in many situations. The question is should you ALWAYS program to an interface.
raveman
May 30, 2008
I think many of you are missing the point. author DOESNT say "lets remove List and Collection and all interfaces!! i hate interfaces!! last time i saw interface i killed it with a hammer!!", but he DOES say "lets remove dao interfaces, because they are useless".

I must admit that it is the most painfull thing in java, i saw few places when dao interface has many implementations, but i dont think it was more than 0,0001% of it(i mean at work when we do only db stuff, i use many dao impls in my home made apps).

I think good example of it will be if you would like to create class representing Cat that will print out "miau" message. Do we need Cat, Animal, Talkable interfaces for it? And if we do need them - do we need them now or can we add them when it will be needed?

However i think we all are too brainwash to dump it. I dont see any of big java players backing up the idea that this is USELESS DESIGN. At work we HAVE TO use dao interfaces or we would look weird. its just how its done, dont ask questiona be one of the ants.

However if you are doing independent projects you can forget about those stupid ideas and extract interfaces at the end of the project. most people cant understand why they are useless, because of Spring and people at Spring have iq like 500 and are always right(i think they have patent for it).
raveman
May 30, 2008
Please can we speak about DAO that everybody is using and not the DAO design pattern? I know its hard to admit that most common use of DAO is database access.

DAO <> DAO DESIGN PATTERN !!
raveman
May 30, 2008
Please can we speak about DAO that everybody is using and not the DAO design pattern? I know its hard to admit that most common use of DAO is database access.

DAO <> DAO DESIGN PATTERN !!
May 30, 2008
I have done some projects changing from Mysql to Oracle and Oracle to Mysql(!). However, it's more often you see people replace Drirect JDBC with Hibernate or toplink.

In my company, we always start with Interfaces first. Let's say programmer A works on service layer and programmer B works on DAO layer. A and B would define/write interfaces first and start programming at the same time.
May 30, 2008
I gotta agree with Ben. In my experience, I've never swapped out the Manager implementation. I have only once swapped out the DAO implementation. In that case, we were supporting multiple versions of a vendor product where each version was implemented on a different DB and each version had a slightly different schema. The DAO layer hid these differences. BTW, this was a C# project so it's not about Java.

Personally, I wouldn't care too much about this, except for one thing. In the IDE (VisualStudio 2008 in my case), I can't just navigate to a method via Ctrl-Left-MouseButton-Click. That'll take me to the method declaration in the interface. Instead, I have to remember to Right-MouseButton-Click, select the Find Usages Advanced menu item, make sure the Interfaces checkbox is clicked in the Find Usages popup, and then press OK. I only do that about 100 times on a slow day.
June 02, 2008
I didnīt see the RSS subscription. Could anyone help me?

Very good articles, indeed.
June 02, 2008
Thanks everyone for the comments!

Wanderson Santos - in recent my site redesign, I forgot to put out the RSS link. It should be there now. Please let me know if it doesn't work.

With respect to the article, actually, I kind of wish I had re-do, because my main gripe wasn't as clear as I had hoped. I think, however, the ambiguity of my argument actually fueled more discussion/debate...which is good.

Basically, raveman hit the nail on the head - I wasn't trying to say that interfaces are a bad construct or that abstraction is a silly/useless concept, only that too often we apply the principle of "programming to interfaces" dogmatically - as though it's some religious principle we should never question! De-coupling is great, but only when you expect that those two things, at some point in the future, may not be coupled together. In other words, if there's only ever going to be one implementation to an interface, prefer tight-coupling. It'll be less code, fewer layers of indirection, etc.

Also, I definitely stated the DAO case too weakly/shallowly. In some cases, moves from MySQL to Oracle are obviously justified. However, I still think that this alone shouldn't necessarily compel you write a DAO interface layer. Unless you're developing an actual product (vs. a single deployment), where multiple RDBMS's need to be supported, there will still only be one implementation of the DAOs living within the system at any one time. Sure, right now they're written for MySQL and in 6 months for Oracle, but a SCM can maintain the differences - they don't need to both live in your system.

With respect to moving from a JDBC-type approach to ORM, I've found that a system with JDBC DAOs often has a de-normalized or redundant domain model to compensate for the difficulties in writing JDBC code. Moving to ORM means not just re-writing DAOS, but also refactoring the domain model classes as well, which means the classes the DAOs accept and return will likely be different. Therefore, the ORM DAO interface still differs from the JDBC DAO interface, and again, programming to interfaces at this layer buys little if anything.

Anyway, thanks again for all the feedback! I've enjoyed reading a your blogs as well.

-Ben
Larry Maccherone
June 02, 2008
Remember, when the GoF wrote their design patterns book, they were talking about C++. There is no such thing as an interface type in C++. What Gamma means when he says, "program to an interface..." is not "use the interface keyword in java". In fact, the link you provide for the "program to an interface..." quote explains this quite well. In that link he talks about how you can use an abstract base class as an interface. Venners elaborates and Gamma agrees that even the idea of using the highest class up in a deep class hierarchy is consistent with programming to an interface. Gamma then elaborates on what he means to NOT program to an interface.


Bill Venners: How can I write to an implementation?

Erich Gamma: Imagine I define an interface with five methods, and I define an implementation class below that implements these five methods and adds another ten methods. If only the interface is published as API then if you call one of these ten methods you make an internal call. You call a method that is out of contract, which I might break anytime. So it's the difference, as Martin Fowler would say, between public and published. Something can be public, but that doesn't mean you have published it.


A keyword "interface" type in java is only one way to program to an interface. Going back to your example, if you had put the meat directly in CustomerManager and CustomerDAO, you would still be following the principle of "programming to an interface..." as long as you used only those limited method calls that you indicate.
March 02, 2009
On moving from a database to another
I once was working for a company which has their own hosted solution and one of the first thing I noticed was they had hard coded references to Weblogic and Oracle specific queries all over.
When I cautiously commented (I was only a week into the company) that - we should avoid such strategy- I was met with the answer we are a hosted solution and free to do what we can
Six months later- the company was bought by another company and we scrambled to get our application work on webshere and host of other databases
My experience is - things happen.
If you are writing a tic-toe program for your son- go ahead and call new
If you are wring a more serious enterprise application- a true of a good software application is - it will undergo lots of changes

On pluggable DAO Impls
On another project - I saw the DAO layer implemented in JDBC being replaced by DAO implemented in hibernate
What made it more painful than it had to be was that the clients of the existing DAO classes were bound to the super classes that the JDBC DAO classes Had we contracted with the DAO implementation y interface- we could have all slept longer.

My two cents...
Harsha
September 01, 2009
our enterprise application is plagued with interfaces. Every class has an interface defined. But there are few instances where we do alternate implementation. For me, this has become more of a liability than the help. I know interfaces are great and they are there for a reason but using them everywhere just to use it is a overkill. Code reading is difficult because you dont know which implementation gets created (in my case) always the same implementation. Visual Studio takes you to the interface file instead of the implemention file so you are always lost in your own code.

We usually take anything good to the extreme and it really starts to hurt us after that.

I totally agree with the author in this regard.

Harsha
August 20, 2011
Very good arguing points. I used to argue on the same lines when I was a programmer. But as I moved up the ladder, I realized why it makes sense. I advise you to write your thoughts, after you architect an application.

BTW, very good post.
An
June 28, 2012
Great, man, (that was regarding the analysis of the use of interfaces which I found useful - thanks!) but I get these errors at the end of this .php page... Check them out : P:

Warning: mysql_query() [function.mysql-query]: Access denied for user 'bennor2'@'localhost' (using password: NO) in /home/bennor2/public_html/includes/bottom.php on line 106

Warning: mysql_query() [function.mysql-query]: A link to the server could not be established in /home/bennor2/public_html/includes/bottom.php on line 106

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/bennor2/public_html/includes/bottom.php on line 107
Comments ()

None so far!


Warning: mysql_close(): supplied argument is not a valid MySQL-Link resource in /home/bennor2/public_html/includes/bottom.php on line 169


Browser (I don't think browser matters here): Firefox.
February 25, 2013
I know it's an old thread but... not everyone uses IDEs. Some of us prefer things like vim and sed.
Jones
May 28, 2016
couldn't agree much, I was excited about oo 16 years ago, but now I think its become very dogmatic - the way some people have adopted the things like 'program to an interface' when you look at some code has the feel of some sort of machine like maoism.
Id go as far as saying usong oo indiscriminately is more damaging thar using simple clean code - if you can't use it appropriately. then don't use it at all. its horrible managing code where every class has an interface - it stinks of cargo cult.
Id argue as the vast majority of a code's lifetime is spemt being read and maintained by others and ypur ultimate responsibility is to program in sociable and cosiderate manner (not catering for imaginary events in the future that are either improbable or will never happen. Reusability should be about giving others something they can as somply as possible understand and change not catering for imaginary genetalizations that will never exist in reality