In The Age Of DRYness - Do We Really Need Naming Conventions For Interfaces?
During past projects / reviews I found the following naming conventions for interfaces and their realizations:
//1.
IService service = new Service();
//2.
Service service = new ServiceImpl();
//3.
ServiceIF service = new Service();
Each
one contains redundant information. Either your are emphasizing the
interface, or its implementation. The information is already contained
in the source code, so both is redundant.
Such naming conventions
are only necessary if you have really no idea how to name the
implementation, so instead of thinking about a sound name, its easier
to rely on existing template.
The lack of name for the implementation is probably also an indicator for it's unsufficient responsibilities. So if you can not find a proper name for the implementation, it is a good idea to think about removing the interface and exposing directly the implementation - then without strange conventions. Actually there are no such conventions in the JDK. The interfaces and their implementations are often even called differently:
Runnable r = new Thread();;
RootPaneContainer c = new JFrame();
TableModel t = new DefaultTableModel();
Remote remote = new UnicastRemoteObject()
The purpose of an interface is the abstraction or decoupling from several implementations. A single implementation do not needs to decoupled with an interface. There are some exceptions from the rule, like the need to use dynamic proxies etc.
An interface realized by a single implementation with strange naming conventions shouldn't be considered as a general best practice...
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
Alessandro Santini replied on Wed, 2009/08/19 - 2:04am
Hi Adam,
Another usual pattern is also:
Service service = new DefaultService();
There are also four good reasons for never exposing the implementation class:
Ciao,
Alessandro
Elwyn Malethan replied on Wed, 2009/08/19 - 2:25am
Alessandro Puzielli replied on Wed, 2009/08/19 - 3:14am
Hi Adam,
In my opinion the interface is matter for the maintenance and the evolution of the software: it's an indication, a landmark about the interanl stucture of the program (the concept of program to the interface not to the implementation quoted by Santini).
For example you have the code
and you prefer to re-write as
( Service is a concrete class and ServiceIF is an interface)
Later, the customer ask you to extend the function of a software component.
The solution iscreate a new class NewService (horrible name but it's an example :)) sharing the public behaviour of Service.
With the first solution, you can write
with the other solution
and you must be more careful for the regression test.
At the least, I think the the interface implemented by one class is an assurance for the future ;)
The bad practise, IMOH, is to use name as
instead a name closer to functional world.
Bye
Alessandro
Bruno Vernay replied on Wed, 2009/08/19 - 4:06am
Adding "transparent" Interfaces makes the code harder to read, navigate and change.
Besides, refactoring tools have improved and if you really need to extract an interface, it can easily be done. So creating Interfaces just in case multiple implementations could be required later is not an excuse.
I like this new movement toward simplification: POJO, no DAO, no Interfaces ...
Bruno
Arek Stryjski replied on Wed, 2009/08/19 - 6:32am
Erik Post replied on Wed, 2009/08/19 - 7:27am
Rogerio Liesenfeld replied on Wed, 2009/08/19 - 8:12am
in response to:
Alessandro Santini
java.lang.reflect.Proxyis as much a "trick" as ASM or CGLIB. In reality, these are simply implementations mechanisms used internally by mocking tools, which users don't really have to know about. In the end, it's the code you write in your unit tests that matter, not the code that the tool providers need to write. And writing mocks by hand is far from effective or productive, if you consider how easy it can be to use a good mocking tool.Seb Cha replied on Wed, 2009/08/19 - 8:53am
I use
Because other classes dont have to know that service is a java interface.
Do you suffix your classes with "Class" ? no.
public class HelloClass {}IMHO, the "IHelloService" was named like this by people that were already using an implementation "HelloService". It was just a lack of refactoring ...
Alessandro Santini replied on Wed, 2009/08/19 - 9:27am
in response to:
Rogerio Liesenfeld
I certainly agree that misuse of what I am saying can lead to overengineering; on the other hand, misuse of the technique described in this post (and you) can lead to poorly maintainable designs.
I also agree that developers should be unaware of CGLIB and ASM; on the other hand, I have seen too many times people writing a final class and then trying to create a mock for it.
I have also seen too many developers adding methods to classes just because they "needed it". Architecture is much safer from being tampered with improper coding.
Last but not least, have seen way more situations in which people wished they had written an interfaces upfront than the other way around.
The bottom line: everything should be done cum grano salis, and this is no exception. However, I still prefer to have one interface more than one less. After all, a Push Down refactoring is not that complicated and can be done after I am absolutely sure there is no need for such an interface.
Ciao,
Alessandro
Ronald Miura replied on Wed, 2009/08/19 - 12:04pm
Rogerio Liesenfeld replied on Wed, 2009/08/19 - 1:47pm
in response to:
Ronald Miura
Rogerio Liesenfeld replied on Wed, 2009/08/19 - 2:02pm
in response to:
Alessandro Santini
I write final classes all the time, and still I mock them just as if they were non-final. And guess what? The tool I use for that uses ASM internally, along with java.lang.reflect.Proxy, java.lang.instrument, and a custom ClassLoader. None of that affects the API used to write the tests, though.
Several years ago, I actually inherited a large Java codebase for a business application, which had a proliferation of interfaces with a single implementation each. With time, I eventually eliminated all of those interfaces, greatly simplifying the codebase and making it more easily maintained. Many other developers worked (and still do) on that codebase, and as far as I know they never missed the pointless interfaces.
Chris Knoll replied on Fri, 2009/08/21 - 3:41pm
I don't see any problem with Service being the interface for DefaultService (as long as the Service it self is more descriptive such as OrderService, SecurityService, etc....). It's quite natural when designing a toolkit to provide default implementations, so having a DefaultOrderService isn't so obnoxious. However, probably better to describe the implementation in the concrete class: AmazonOrderService, Mock Order service, etc.
-Chris