Implicit Interfaces

ImplicitInterfaceImplementation - from Martin Fowler is an interesting piece where Martin suggests that it would be useful to be able to provide alternative implementations of a class’s implicit interface. That is, given a class that does not inherit from an interface, it’s sometimes useful to be able to split the class into an implicit interface, the public operations that it provides, and treat that as if it were explicitly declared as an interface from which the class derives. This would be useful in testing as it would allow you to mock up things that are currently difficult to mock up. It’s an interesting idea and it’s generated a lot of talk. I’m not sure it’s good though, it smacks of making things easy that are already easy if you approach the problem with enough discipline…

I think one of the biggest problems with this idea is, as Barry Kelly says over on Entropy Overload, classes like that often have multiple implicit interfaces and they’re not always public.

I find that in C++ I tend to operate with explicit interfaces much of the time, it often works out easier in the long run to develop a class interface first, especially when developing in a TDD style. I write the test, I write the code under test, it needs to access another object to I work out the interface, implement a mock from that interface and, eventually, write tests for the object and develop the object. This is pretty much what Ian G suggests, work only through interfaces. It does require a little more discipline and it is, sometimes, overkill but it works pretty well.

Of course Martin’s suggestion would make it easier to use third party code without wrapping it up in a shim of your own. Personally I think it’s a good thing to get in the habit of segregating third party code and putting it behind a thin, object based firewall of your own devising. The shim/wrapper code allows you to blend the alien API into your standard ways of doing things and gives you a chance to refine the abstraction that the third party API provides. Chances are their abstractions are in terms of the problem that they solve whereas yours should be in terms of the problem that you are solving and might only use a small part of the API… What’s more, if you have slipped in an interface you can test without the third party code and you can, potentially, replace the third party code with other code if required…