Wednesday 17 August 2011

Implementations of interfaces - prefixes and suffixes

I recently asked a question on Twitter about how to use some common classes name prefixes/suffixes to go with an interface to see if there are best practices out there.

Common Java prefixes and suffixes

The design pattern of an interface together with one or more implementations is not always considered favourably these days. However, in certain circumstances it can be the right choice. One of these cases is the OpenGamma platform, my day job.

At OpenGamma, we are building a platform that will be implemented by different teams in different companies. Those implementations will typically not be under our control and frequently will exist already. Thus, the platform must impose the minimum design penalty for integration, which clearly implies an interface, as an abstract class imposes more constraints.

Within OpenGamma it is also necessary to provide certain standard classes that implement the interfaces. This might be for examples, or other functionality in a different part of the stack. Naming these classes that implement the standard interfaces was how I started the Twitter conversation.

As a result of the Twitter thoughts, other discussions and my own thoughts, this is where I got to:

  • Foo - The interface ultimately defines the concept, so it should have the best name.
  • AbstractFoo - An abstract implementation intended to be used as the base of a hierarchy of classes.
  • BaseFoo - An implementation intended to be used as the base of a hierarchy of classes, where the base class could be used on its own if necessary.
  • DefaultFoo - A "default" implementation that would be appropriate for the majority of typical use cases.
  • SimpleFoo - A "simple" implementation with no unexpected functionality, perhaps as an example or as a mock. A simple POJO would be a good "simple" implementation.
  • {Descriptive}Foo - Other implementations should describe what makes them unique.

Note that some of these "best practices" can be combined. For example, a Foo interface might have a BaseFoo implementation intended for subclassing with DefaultFoo as the standard and most commonly used one.

Some other suggestions were:

  • BasicFoo - This appears to be semantically equivalent to SimpleFoo, so its mostly a preference issue.
  • interface IFoo, class Foo - This naming convention is seen in some places, but is not generally thought of as good Java style.
  • FooImpl - This naming convention has some supporters, but generally seems clumsy.
  • StandardFoo - Similar to DefaultFoo, but less widely used
  • GenericFoo - Never seen this one myself

Two other thoughts on FooImpl. Firstly, it does group well in auto-complete (Foo ctrl+space). For method names I think that is useful, but it doesn't convince me here. Secondly, it was suggest that FooImpl should be used for IoC dependencies. This seems to me to be an indirect tie of application to IoC container, which I dislike.

Summary

There are no cast-iron definitions here, however those in the first list are probably a good place to start from when creating your own "best practices" or "coding standards".

Opinions welcome as always.

17 comments:

  1. There's a few other important variations on the theme worth considering:

    FooUtils - a collection of static methods or (arguably better) a singleton containing functionality useful across all Foos

    FooBuilder/FooFactory - for creating Foos (especially immutable Foos)

    XxxFooDecorator / XxxFooProxy - an implementation of the Foo interface that works by modifying behaviour of a pre-existing instance

    How best to represent immutable vs. mutable Foos, if Foo should lend itself to making such a distinction? Distinct packages, or as part of the simple name?

    What name should be used for pseudo-mixins? (Partial implementations of Foo intended to be composed into a "full" Foo instance and have methods delegated)

    ReplyDelete
  2. Regarding IoC, I meant that the component responsible to provide the implementation hides it (that is you are not going to do new FooImpl() yourself). but I agree it's a detail.

    You should try to build your convention with things more complex than Foo. When your interface has two words, you might be tempted to put the qualifier in the middle.

    I also find confusing that Base is not abstract. I would expect it to be, really. That being said, it brings another confusion between Abstract and Base...

    ReplyDelete
  3. "The design pattern of an interface together with one or more implementations is not always considered favourably these days". Would be interested to hear the arguments against using interfaces. What are the alternatives?

    ReplyDelete
  4. Use xManager / xHandler / xService when you can't think of any better name for your singleton or gave up on conjugating x as a verb http://en.wiktionary.org/wiki/-er#Etymology_1 :)

    ReplyDelete
  5. As a base class for decorators, proxies and such I usually use "ForwardingFoo".

    ReplyDelete
  6. Kevin, Ophir, Andres, I hope to write another post about other prefixes/suffixes soon, see latest twitter query.

    Stephane, the distinction between Abstract and Base is subtle, and perhaps not warranted. In general I would prefer AbstractFoo as it is clearer.

    Ross, some proponents argue that interfaces are over-used, especially when there is only one implementation. For cases like the OpenGamma platform, we don't control the implementations, so an interface is the right design. If you do control your implementations and can refactor freely in the future, then it is worth considering not having the interface until you need it.

    ReplyDelete
  7. Where possible, I like to look at what behaviour differentiates it from its specializations.

    For a security policy, the base version might allow everything, where subclasses have the ability to restrict behaviour - so AllowEverythingSecurityPolicy or OpenSecurityPolicy is a better name than 'BaseSecurityPolicy'.

    If the base TextRenderer which ignores markup when its subclasses support various other forms of markup, 'PlainTextRenderer' might be a good name.

    For a message destination where the base version drops everything on the floor, and subclasses override to do emailing / faxing / SMS etc, then NullDestination, etc.

    Generic names like 'BaseXxxx' or 'SimpleXxxxx' should be used as a last resort when there's no better way to differentiate the behaviour.

    ReplyDelete
  8. I'd stay away from things like AbstractFoo and FooImpl which just replicate the abstract and implements keywords. They don't give any meaningful context for what the classes actually do.

    Similarly for BasicFoo, DefaultFoo and SimpleFoo: they're just synonyms for Impl or Abstract and are, effectively, meaningless.

    ReplyDelete
  9. My opinions:
    So far as it is possible, specifics are best for classnames: {Descriptive}Foo.

    AbstractFoo is okay for abstract implementations, but should become more rare when Java allows method implementations inside Interfaces.

    Base/Basic/SimpleFoo or FooImpl is acceptable when the interface is Foo, and you cannot think of a single distinguishing feature of the implementation.

    GenericFoo might be discouraged because the term is overloaded: Foo vs. GenericFoo.

    IFoo is discouraged in the Java community AFAICT, though other communities have adopted this standard. Using IFoo in Java is the equivalent of an accent in spoken languages. :-)

    If the interface intended to be the root of a hierarchy (specifying "primary behaviors"), Foo is the appropriate name.

    If the interface is inherently cross-hierarchy and is meant to be used as a "side behavior", adjectivization might be appropriate, e.g. Fooable, Serializable, Iterable. A "side behavior" is typically limited to one or two methods that ordinarily supplement rather than define a class's capabilities.

    ReplyDelete
  10. Ha, that was Foo vs. Generic<T>.

    ReplyDelete
  11. I've come to like IFoo, which came from the Windows world and is also the standard on the Eclipse platform (and in TestNG, obviously).

    I'm not religious about it, but I do think that one should use a syntactic convention to differentiate interfaces from concrete types. Opponents tend to say that you shouldn't care whether a type is an interface or a concrete class, but it's false, I do care greatly. With a syntactic convention, I can take a look at a piece of code and know immediately how "pure" (how many interfaces it uses vs/ concrete types) it is. Code that uses 100% interfaces is typically very easy to test, mock and reuse.

    Also, when I see a type, I want to know if I can simply "new" it or if I need to find some builder or implementation thereof, another argument in favor of the syntactic convention.

    ReplyDelete
  12. I prefer the way the JDK does it:
    - Foo, the interface
    - AbstractFoo, so methods can be added to the interface without having to rewrite all implements
    - {Descriptive}Foo if there is something special to make to put in {Descriptive}, DefaultFoo otherwise.

    ReplyDelete
  13. Paul, Ricardo, James, I agree that meaningful class names are generally best. However, when designing an open source library or platform like OpenGamma you have to be aware that it can be easier for someone to learn if there are common naming patterns.

    Geoffrey, I think my proposals are pretty close to those you've listed, although I wouldn't say the JDK is perfectly consistent.

    Cedric, I used to like prefixing my variables too, but I got over it, partly thanks to IDEs. Your comment about purity and testability is interesting, but sadly I don't buy the argument of designing for tests/mocks. We should design code for readability, usability and learnability - testing, mocking and reuse should be secondary considerations.

    ReplyDelete
  14. Stephen,

    FYI I didn't say anything about variables.

    ReplyDelete
  15. Cedric, I know you didn't, but surely there is a connection between the two? Now, in languages that had a weaker type system, I could see a use for type-representing prefixes. But in Java and similar, they just seem to get in the way.

    ReplyDelete
  16. Naming such as IFoo also doesn't make much sense in the context of DDD.

    ReplyDelete
  17. Afaik in OO sense prefixes like Abstract, Base etc. don't make sense unless you use the hierarchy for code reuse or framework style which likely is your need. But I would rather have *only* descriptive names. Foo is a concept as you said. Its abstract implementation is a specialization which lends itself in a given direction already. So what does it add? Is it an array based base implementation? ArrayFoo. Does it add a template for subclasses? TemplateFoo. But finding such names is (like all good names) very hard. Technical names (e.g. Abstract) is much easier.

    ReplyDelete

Please be aware that by commenting you provide consent to associate your selected profile with your comment. Long comments or those with excessive links may be deleted by Blogger (not me!). All spam will be deleted.