'Programming to interfaces' strikes again

Why oh why do people create interfaces which are implemented only by a single class. There's no polymorphism there that necessitates the interface. What value can there possibly be in writing that superfluous code?
For the umpteenth (well, OK, second) time , 'Programming to interfaces' does not mean 'create one interface for every concrete class'.

Extract an interface if you have two or more classes doing the same 'things', but with differences in the implementation, or if you are designing a framework and want to define a contract for future extension. Not otherwise.

10 comments:

Kerry Buckley said...

One reason for doing that is to allow the object to be mocked or stubbed. This is less of an issue now most (?) mocking frameworks allow mocking of classes, of course.

Best bet is to switch to Ruby and forget about interfaces forever ;-)

Jeffrey Palermo said...

Perhaps this is encourage by the use of an IoC container. What container do you use, and do you use it to construct classes that do not implement an interface?

For example, if I have CustomerRepository, which has Save(Customer), and I have no interface, would you use an IoC container to create it, or would you write a "new" statement? If "new", who would be responsible for creating it?

Sidu said...

Fair enough - there are certain situations where you're forced to do this even for one class, like developing a framework or, as you said, using something like an IoC framework to manage complex object dependencies or for a mocking framework.

But in cases where there is no 'environmental' factor requiring this, creating interfaces for no particular reason is a complete waste of time, not to mention forcing you away from evolutionary design.

This post was based on a code submission made as part of the TW interview process, which I happened to review. The scope of the problem is so small that using something like PicoContainer isn't necessary. Indeed, there was no need for those interfaces whatsoever, either to satisfy a framework or to allow polymorphism (there was just one class implementing the interface).

In my opinion, if there is no IoC framework, deciding who is responsible for the creation of an object is entirely based on context. Maybe it's a factory (construct a Car with four Wheels), maybe the owner of the object creates it (a Tree creates its own Leaves). It's not something you can decide in isolation.

perryn said...

Sorry, but I don't agree.

The need for other implementations is not the only reason you might want an interface.

Using a class directly, without an interface ( in Java at least ) couples those two classes together. (The fact that trying to do isolated unit testing often drives you towards the interface shows this.)

The key to evolutionary design is coding in such a way that the system is very loosely coupled and so can be re-arranged easily.

I consider that the use of interfaces like this actually ENABLES evolutionary design.

rams said...

I would agree with perryn. I am of the opinion that Interfaces help de-couple classes. Doug T, an MS developer evangelist talks about the dilema here. So, like most things in life, it depends.

Also, maybe the interview submission went too far but had they not used interfaces, I am not sure if they would have effectively communicated that they are aware of interfaces and its use, although just be using it, you don't prove anything, but atleast you can assume they have some knowledge. Interview submissions are a fine balance. You don't want to over-engineer the solution but you also want to showcase your talents. What if a very clever solution was lost in translation?

WolfDancer said...

I thought the post was about the abuse of IClass desgin, which probably means that the author recognizes the reason for such design for an IoC container, or ease of testing for the typical 'IRepository' . If so, why are the comments about when it is appropriate to do it???

Another thing that I would like to comment is that I HATE half of the 'clever' design I run into from time to time!!! The only clever design should just be a design that solves a complicated problem in such a simple way that everyone can look at it and understands it.

Will Sargent said...

If you look at mockobject libraries such as EasyMock, they explicitly only allow you to mock interfaces, to define the boundry between one system and another. Mocking a class is something that was only grudgingly allowed with the "class extension" library.

Sidu said...

Please see my next post for more on the topic. My response was getting too big for comment :)

caufield said...

I am too naive when it comes to designing interfaces, but this one questions has always intrigued me.

Why do we need interfaces when we have the concept of abstarct classes.. Isn't makin all the methods of an abstartct class equivlent to designing an abstaract .. Plus an abstract class has other advantages.. like u can have non abstarct methods which need not be impplemented by classes extending this abstarct class... SO why and ahere exactly do i need (or i shud prefer) an interafce over an abstarct class.

Michael R. Head said...

Take an interface of an abstract class in almost any context. Any common functionality is often better delegated to another class.

The only reason you would actually want the common functionality in a super class is if your methods were interacting in some way. But once you start mixing and messing methods in a hierarchy of classes, everything quickly becomes a mess, and it becomes very hard to come back later and adapt your design as the problem changes.

Abstract classes (in Java at any rate) tie you to a specific branch of the class hierarchy. If you're using the abstract class to reduce coupling, you've just shot yourself in the foot, since if you had simply used an interface, you would have been able to implement it with (an extension of) any class you choose.


Now, I am in favor of abstract classes for sharing common data and (a few) operations over those data. For example, a graphical shape (in a given design) is going to have some top left coordinate. Those data and a couple functions to mutate those data should go in an abstract Shape class.


I would point out that I generally agree with Sidu here. Unnecessary use of interfaces is pointless. You don't need to componentize every single packet of functionality in your system.

And coupling isn't universally bad. Major components, of course, should be decoupled from each other, but their interiors needn't be. For programming-in-the-small, there's just not real benefit, and a lot of extra .classes and ways to instantiate them (when do I call new? when do I use a factory method? when do I use a factory?).