Which is your naming convention for implementation classes? Do your prefer FormDataValueImpl or IFormDataValue ?
Intrinsically I should be pleased about this question – at least someone seems to care about naming conventions … but sorry, both conventions are little more than crap. Unfortunately these patterns are very popular, so my criticism will have little effect. Here you are:
Criticism of Single Implementation Interfaces
Generally both naming conventions often seem to solve the problem “One Interface with exactly one Implementation”. This approach is already flawed, the idea of an interface being implemented by only one interface for all time seems to me very restrictive and not realistic.
Almost every code I saw using these naming conventions also contained casts to the implementation type of the pattern:
Interface intrfc = ...;
// other code
InterfaceImpl impl = (InterfaceImpl) intrfc;
The interface developer usually know that this usage is not intended, but third party user often do not.
Using interface and implementation in the same context violates multiple SOLID-principles. In any case the development of a second implementation is impossible without cleaning up the dependent code.
I is a syntax encoded Hint
Prefixing every interface name with an I, provides a hint for the reader, that is ignored by the compiler. This leads to redundancy with the definining token interface.
I thought that it is a win, that I can use an object only knowing its type and not needing to know whether this type is an interface or a class. Of course even with the I -convention, I can keep doing so, but if we want to change an interface into an implementation class, this would need a renaming which leeds to incompatibilities in dependent code.
Another point: We get into conflicts with libaries using other conventions. We can not rely on the prefix to identify interfaces, because many libraries do not use this convention. So even if this convention was fine, it is nearly impossible to enforce it usage in the whole project.
Robert C. Martin writes in in Clean Code a similar criticism and prefers the other naming convention. Well – it stays open, whether he really prefers it or if he only rejects it less.
Impl is lazy
Coming from an interface FormDataValue it is very easy (and lazy) to suffix the interface name for getting the name of the new implementation FormDataValueImpl . No need to think about the name, no waste of time. Yet I think that especially naming should not be thought of to short – later readers will appreciate a longer thinking process.
I already mentioned that Robert C. Martin prefered this convention, yet there are many good reasons found in Clean Code, that would reject it:
Given an interface and an implementation the implementation will probably have some specific property that is characteristic to itself – and what would be more intuitive than coding this property into the name of the implemenation. The Impl-suffix is practically no information about the way the implementation works.
Another problem from my point of view is, that the Impl -convention is getting more and more an indicator of the “Single-Implementation Interface” pattern. This means the naming could mislead third party users to think that there is only one implementation. Thinking so leads to users that do not search for the correct implementation, because they think they have found the one and only implementation.
Better OO-Design, better Naming Conventions
To extend the criticism with some constructive facts I try to make a proposal for a better naming convention. Maybe it is not optimal, but at least it does not share the upper weaknesses.
At first I would ensure, that no interface has one and only one implementation. Be consequent: If there is exactly one implementation for the interface (and this will be so for the next 10 years) then skip the interface and replace the usage sites with the implementation.
If there are good reasons that implementation and interface must be kept separate, then try this: If your inteface is FormDataValue and you need a name for your implementation, then try a name that is characteristic for this implementation, e.g.
- PrimitiveFormDataValue (if the contained data type is characteristic) or
- WebFormDataValue (if the usage context is characteristic) or
- DirectFormDataValue (if it is characteristic, that the class is not cached)
If really no characteristic property exists, then there holds at least on property: The implementation is the default implementation. Consequently DefaultFormDataValue is a proper name.
Yet – some might argue that the prefix Default is not better than a suffix Impl . There are some arguments:
- Logically an interface could have multiple implementations ( Impl), but only one of the is Default.
- Technically it is not possible to have multiple Impls, and also not multiple defaults Default (because of name conflicts). This is only correct in the latter case.
- Default is more robust for future work. Adding a compact implementation would lead to two classes FormDataValueImpl, FormDataValueCompactImpl in the Impl case and DefaultFormDataValue, CompactFormDataValue in the Default case. The latter is shorter and more descriptive.
- Default rises the question whether there are non default implementations. Anyone casting to the implementation type will be pointed to that and eventually will also check on other implementations.
- Maybe later on a new implementation should replace the old on (e.g. CompactDataValue is the new default). A renaming from CompactDataValue to DefaultDataValue lets the reader know that the default implementation has changed, a renaming from CompactDataValue to DataValueImpl seems like a technical trick.