Java Champion / JavaOne Rockstar Adam Bien (adam-bien.com) is a self-employed consultant, lecturer, software architect, developer, and author in the enterprise Java sector. He is also the author of several books and articles on Java and Java EE technology, as well as distributed Java programming. adam has posted 59 posts at DZone. View Full User Profile

In The Age Of DRYness - Do We Really Need Naming Conventions For Interfaces?

08.19.2009
| 3703 views |
  • submit to reddit

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...

From http://www.adam-bien.com

Published at DZone with permission of its author, adam bien.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

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:

  1. The good old Design Patterns advice: "program to the interface not to the implementation"; this will let you change the current implementation with another one should the need arise over time;
  2. In a software engineering world where automated testing, dependency injection and mocking are becoming increasingly popular techniques, interfaces let you mock the implementations without recurring to (what I define) tricks like using ASM or CGLIB. You can simply mock an interface by creating a new concrete one which contains the behaviour needed for testing, without recurring to frameworks.
  3. It's perhaps a rephrasing of point 1., but you may want to use an interface simply because that  class represents an "extension point" and, although you still do not have multiple implementations, you may want your architecture to cater for it.
  4. Because refactoring and extracting an interface out of a class later in the development cycle can be cumbersome - developers using methods that should not belong to the interface, etc. We have all seen that.

Ciao,

Alessandro

Elwyn Malethan replied on Wed, 2009/08/19 - 2:25am

Did we ever need naming conventions for interfaces and were they ever beneficial? In my experience they've just served to annoy and obfuscate.

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

ServiceIF service = new Service();

 and you prefer to re-write as 

 Service service = new Service(); 

( 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

 public class NewService implements ServiceIF//bla bla

 

  with the other solution

 public class NewService

 

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

ServiceIf, IService, ServiceInterface

  instead a name closer to functional world.

 

Bye

Alessandro

 

 

Bruno Vernay replied on Wed, 2009/08/19 - 4:06am

My experience has been that interfaces, like some other "architectural style" or "best practice", are often over-used without thinking. Everything has a price.

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

Hi Alessandro, 1) If you declare class final you will be able to replace it in future with interface with the same name, and add second implementation. 2) Should development tools (testing frameworks) force us to change class structure? Some will say yes, some will say no. We don't let tools like Eclipse or SVN do it, but we accept JUnit to do it. Well I'm still not sure about it... 3) If you like let other people to extend your interface - yes, but if you don't allow clients of your code to do it your code is probably over engineered. 4) Why you allow other developers to use method which should not be exposed? Don't blame others for making all methods public. There is much better explanation why author of this post is correct in Jaroslav Tulach's Practical API Design (chapter 6).

Erik Post replied on Wed, 2009/08/19 - 7:27am

I personally find names such as ServiceImpl or ServiceIF abhorring. IService, on the other hand, is pretty non-intrusive and practical, if not a 100% DRY. I don't always want to have to use my IDE/editor to find out whether something is a class or an interface. If you do have an IDE handy, this is covenenient for autocompletion purposes. Wicket, among others, uses this as a naming convention, and I believe it's also common in .NET. If nothing else, it can be used as a placeholder until you come up with a better name.

Rogerio Liesenfeld replied on Wed, 2009/08/19 - 8:12am in response to: Alessandro Santini

Alessandro, the kind of thinking you are describing tends to lead to over-engineering, which causes great harm in real-world projects. About the four reasons you listed:

  1. The advice from the Design Patterns book wasn't meant to be read as "create separate interfaces for everything", but as "if you have a separate interface already, then use it to declare your variables, fields, parameters and return types, instead of using the implementation type".
  2. java.lang.reflect.Proxy is 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.
  3. Creating a separate interface without a real need is pure over-engineering, which adds certain cost in exchange for a dubious eventual benefit. Besides, modern Java IDEs make it easy to introduce them later, should the need arise.
  4. It can be cumbersome, but it can also be quick and easy. If you do create the interface up-front, then you and everyone else will inevitably pay the price for the extra complexity, for the whole life of the project.

Seb Cha replied on Wed, 2009/08/19 - 8:53am

I use

HelloService service = new DefaultHelloService();

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

Therefore, EJB is crap as it requires interfaces for everything. :)

Rogerio Liesenfeld replied on Wed, 2009/08/19 - 1:47pm in response to: Ronald Miura

Not true in EJB 3.1, which made interfaces optional.

Rogerio Liesenfeld replied on Wed, 2009/08/19 - 2:02pm in response to: Alessandro Santini

I agree, the misuse or abuse of anything can only lead to bad results. Design Patterns in particular, from my experience are much more often misused than otherwise. In most cases the developer simply wants to use them because it will look "cool".

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

The JDK got it right with how they named their interfaces: they didn't just make them different from the implementation, the explicitly made them _adjectives_ so that the name of the interface describes exactly what it is doing....It's Runnable...It's Shapelike....it's Serializable....etc.

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.