I just stumbled upon this article by Bruce Wallace:
Design Markers - Explicit Programming for the rest of us
Bruce describes a way to use interfaces to explicitly document things about your classes that can't otherwise be enforced in code.
Bruce's example: Immutable classes
Suppose you have a class that should be immutable. There is no immutable
keyword in Java, so you can't document this fact directly in your code (or, for that matter, make the compiler enforce this requirement). In order to inform other developers working on your code that they shouldn't add setter methods to your class (in order to maintain the immutability requirement), you could define an empty interface named Immutable
that relays this requirement to others working on the project:
public interface Immutable {}
Any classes that should be immutable then simply implement this interface:
public class UserRole implements Immutable {
...
}
This way, any other developers know right away that they shouldn't add setters to your class. The interface serves solely as a way to explicitly document this aspect of your class.
Another example: Internal framework code
Most frameworks contain at least a few classes that exist to support the internal operation of the framework and which normally should not be used directly by users of the framework. An Internal
marker interface could explicitly identify such classes to end-users.
This also provides a good example for how design marker interfaces can help to organize JavaDoc documentation. The JavaDoc comments for Internal
would explain that it is an interface implemented by classes meant for internal use only, and would provide a single point of reference for describing internal classes. This helps maintain the DRY principle: instead of repeating the same comment for every internal class, you can write the documentation once (in the Internal
interface JavaDoc). Anything about internal classes that needs to documented at a later date can then be updated in a single place.
You also have the added benefit that all your Internal
classes are listed in one place in your documentation - they will appear in the "All Known Implementing Classes" list in the JavaDoc for Internal
.
Taking advantage of JavaDoc
This approach is meant to be used in combination with JavaDoc. For example, the JavaDoc for the Immutable
marker interface can explain to developers that Immutable
is a marker interface, and that it should be implemented by classes that are intended to remain immutable. As a side effect of adhering to this pattern, you can also browse the JavaDocs for your project and instantly see which classes are currently immutable, by seeing which classes implement the 'Immutable' marker interface.
What about design marker annotations?
The original article was written in 2003. Now that Java has annotation support, I could also see this same concept being implemented with annotations instead of interfaces: in fact, the @Deprecated
annotation is a good example of Wallace's original idea. The @Deprecated
annotation aids in the documentation of your code, rather than actually changing the behavior of your code. Annotations also give you the power to extend the "design marker" concept to individual methods in your classes.
I can see many interesting uses for this idea, especially the annotation-based variation of it: for example, an @Experimental
annotation could be a very useful way to document features that are "in-progress" and more subject to change that other areas of the code base.
And now...my question
So, my question is this: Has anyone here applied Wallace's "design marker" concept to real-world projects? If so, did you find it useful? If not, why not?
I'd be very interested in what others think of this approach to documenting code, especially the annotations-based variation that I presented here.
EDIT: But what's the point???
David raises a valid concern: why bother with all this design marker interface stuff? As he says, "code should be code." After all, you could express the same requirements in a code comment. The design marker pattern seems to couple two different (although argubly related) concerns: it tightly binds documentation concerns to the code.
I've been playing devil's advocate in the comments, as I'm ambivalent about the usefulness/non-usefulness of the design marker pattern. However, to expand a bit on what I've been saying in the comments, I'm currently wondering if it's really such a bad thing to couple code to documentation a bit more tightly. After all, aren't most of us striving to write self-documenting code? In my mind, the design marker pattern seems like one way to achieve that goal, and even go beyond it. At the same time, I can see potential for abuse, and it would be less than helpful to try to work on a project that defined a design marker interface for every tiny little business rule or domain-specific concept.
I'm hoping the discussion picks up and we can get input from people on both sides of the issue. I'm interested to see what people have to say on this topic.