Java, Programming, Software

Programming to Interfaces Anti-Pattern

Here’s a personal bete noir. Interfaces are good m’kay? They allow you to separate function and implementation, you can mock them, inject them. You use them to indicate roles and interactions between objects. That’s all smashing and super.

The problem comes when you don’t really have a role that you are describing, you have an implementation. A good example is a Persister type of class that saves data to a store. In production you want to save to a database while during test you save to an in-memory store.

So you have a Persister interface with the method store and you implement a DatabaseStorePersister class and a InMemoryPersister class both implementing Persister. You inject the appropriate Persister instance and you’re rolling.

Or are you? Because to my mind there’s an interface too many in this implementation. In the production code there is only one implementation of the interface, the data only ever gets stored to a DatabaseStorePersister. The InMemory version only appears in the test code and has no purpose other than to test the interaction between the rest of the code base and the Persister.

It would probably be more honest to create a single DatabaseStorePersister and then sub-class it to create the InMemory version by overriding store.

On the other hand if your data can be stored in both a graph database and a relational database then you can legitmately say there are two implementations that share the same role. At this point it is fair to create an interface. I would prefer therefore to refactor to interfaces rather than program to them. Once the interaction has been revealed, then create the interface to capture the discovery.

A typical expression of this anti-pattern in Java is a package that is full of interfaces that have the logical Domain Language name for the object and an accompanying single implementation for which there is no valid name and instead shares the name of the interface with “Impl” added on. So for example Pointless and PointlessImpl.

If something cannot be given a meaningful name then it is a sure sign that it isn’t carrying its weight in an application. Its purpose and meaning is unclear as are its concerns.

Creating interfaces purely because it is convenient to work with them (perhaps because your mock or injection framework can only work with interfaces) is a weak reason for indulging this anti-pattern. Generally if you reunite an interface with its single implementation you can see how to work with. Often if there is only a single implementation of something there is no need to inject it, you can define the instance directly in the class that makes use of it. In terms of mocking there are mock tools that mock concrete classes and there is an argument that mocking is not appropriate here and instead the concrete result of the call should be asserted and tested.

Do the right thing; kill the Impl.

Standard

2 thoughts on “Programming to Interfaces Anti-Pattern

  1. Iván Párraga García says:

    I agree sometimes to use interfaces is an overkill when you have only one reasonable implementation, but I don’t like the example you’re using (the persister one). I like having the persistence layers isolated from the rest of the application and I like having a non-technological-dependent name for the INTERFACE. I think that DAO pattern is one of the more useful. It’s nice having your application ready to deploy in different clients with different persistence options by changing the injection of the implementation instance.

    I also agree that “If something cannot be given a meaningful name then it is a sure sign that it isn’t carrying its weight in an application”, but sometimes you don’t have option… Think about RMI or other situations where you need to apply the proxy pattern because of technology limitations.

    Iván

  2. I prefer the Repository (http://martinfowler.com/eaaCatalog/repository.html) pattern to DAO, DAO seems too leaky. It kind of implies that you will be accessing data; maybe, maybe not, backends come in all kinds of flavours these days, you might actually be using a service to fulfil the request.

    I agree that you cannot do much about legacy implementations like RMI or EJB (1, 2) except to pretty them up. However I have encountered this anti-pattern more than I have encountered applications that actually use RMI.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s