Search code examples
apiinterfacenaming-conventionsnaming

Naming Convention for Class/Interface "Default" Implementation


I've seen the canonical class/interface naming questions on StackOverflow and read a lot of other opinions on the subject, but I have a related question that I'm not sure is answered in any of those places. I tend to hate either the IInterface or ClassImpl naming conventions because they're unnecessary (given modern IDE's), make the code harder to read, and in many cases the need to use one of those naming schemas seems to imply an incorrect design.

However, I often run into a scenario where I have an interface that I want to expose as part of my API (usually in a separate package), and then I create an abstract implementation of the interface to contain some common functionality that I expect most (but not all) concrete implementations to derive from. For example:

public interface Foo {
    public String getBar();
}

public abstract class BasicFoo implements Bar {
    private String bar;

    @Override
    public String getBar() {
        return bar;
    }
}

In practice I tend to prefix the implementation name with Basic, but what I'm doing is essentially exactly what some folks are using the Impl suffix for: providing a basic/default implementation. I could try a name that implies that it's a Foo backed by in memory storage (for example of Bar), but that always capture all the functionality in BasicFoo. I'm also not convinced that I should throw out the interface and expose the implementation directly because the interface provides additional flexibility and decoupling.

Thoughts on a better way to handle this scenario, or a logical naming convention?


Solution

  • A common pattern in the Java world is call the abstract, incomplete implementation AbstractSomething; for example AbstractList or AbstractButton. Both the interface and the abstract class are exposed to clients. The idea behind this is that the abstract class serves as a starting point when using the API. This is useful especially for interfaces that define many methods and complex contracts, such as java.util.List. Most of the methods of the interface are implemented in terms of a minimal set of abstract methods that the client has to provide.

    For example, to implement a list based on AbstractList you only have to provide an implementation for the get(index) and size() methods. All other operations - iterators, indexOf, subList, hashCode ... - in the end delegate to these two.