Maximize your Design ROI with Marker Interfaces and JavaDoc, Page 2
How do Design Markers compare to other methods for the problems they solve?
Today, design and implementation are expressed in different languages, and this is the root problem that Design Markers attack. While implementation is embodied in artifacts like source code, build scripts, and configuration files, design is kept in artifacts like UML diagrams, design models, or even primitive word processor documents. Because they can't express design choices directly in their implementation languages, implementers must use manually enforced programming conventions, and so naturally, they need to always be cognizant of those design choices. However, without an expensive round-trip design tool, "the blueprints" are not typically at hand (or even kept up to date). Because design choices are spillage in the shuffle between design and implementation, developers are often unaware of them and therefore fail to maintain them. The problem only gets worse over time as development mode turns into maintenance mode, often with personnel turnover. Finally, since this problem is just a special case of the general problem of human communications, its severity grows rapidly with project size.
So, design choices go unknown by the harried new hire bug fixer. The self-assured experienced developer who is mightily refactoring code is not reminded of why his seemingly more optimal version of a class, never the less, breaks the overall system. Moreover, while testing might discover broken contracts after the fact, it is much better to prevent them. Good programming practice says that things requiring synchronization should be proximate to each other in the source code. There is nothing in more need of synchronization than "what the design decrees" and "how and where the implementation fulfills it".
A special mention must be made about the problems associated with refactoring in the absence of design markers. Often programmers "clean up code" while adding a new feature or fixing a bug, even though they were never "briefed" on the design choices governing that code. Even those who were briefed don't have perfect memories. Reasonable programmers will make locally appropriate, but globally inappropriate, changes when they are not conscious of the tradeoffs made for the good of the entire system. Worse, the consequences of breaking a design contract may be not be a functionality failure, but instead a performance failure. Since unit tests focus on testing functionality much more than performance, these defects may not be discovered. In addition, even changes that improve the performance of an individual unit may, in fact, hurt the performance of the entire system. And this regression is even less likely to be caught because system level tests (like integration and acceptance tests) are done much less than unit tests. Again, preventing breaks is much better than trying to catch them later via testing. Having design markers, not only makes developers aware of pre-existing contracts, but provides a good trigger for a design and/or code review, namely, the changing of a design marker (i.e. a contract) which, after all, is literally the same as changing the published interface.
So, why aren't design choices recorded in source code more often? Mostly, because there has been no clear place to put them. The extant choices are (1) simple comments, (2) custom JavaDoc tag comments, and (3) proprietary markup added by round-trip design tools. If you have the budget for fancy tools and their associated developer training, more power to you. If not, or if you want to use a more portable mechanism, there are comments. However, comments, whether plain or in JavaDoc tag form, do not provide the Design Marker benefits discussed ahead.
A variation on simple comments is to invent and use custom JavaDoc tags (e.g. @Immutable, or @TypeSafeEnum). This approach is given more encouragement with the new JDK 1.4 version of JavaDoc that allows simple command line parameters to make JavaDoc aware of your invented tags and produce "official" documentation in the generated HTML. However, the HTML generated by JavaDoc is still just text (albeit with nicer paragraph headers). A Design Marker (like all Java Interfaces) causes JavaDoc to generate hyperlinks back and forth between its definition and the definitions of each of its heirs. While arbitrarily elaborate processing of your custom JavaDoc tags can be had if you learn the Doclet framework & API, and write custom Doclet plug-ins, this option does require tool development time, and therefore, money.
A summary of benefits of Design Markers over JavaDoc tags follows:
- Design Markers have no start up costs (unlike Doclet plug-ins).
- Marker interfaces are automatically inherited and therefore automatically referenced on all subclasses, so JavaDoc provides hyperlinks to all documented requirements. JavaDoc custom tags aren't inherited.
- JavaDoc creates hyperlinks to/from each class and its inherited interfaces, thus navigation to/from uses of Immutable and the definition of Immutable is trivial. JavaDoc custom tags (e.g. @Immutable) do not generate hyperlinks, only simple text.
- Custom JavaDoc tags require JDK 1.4 and special JavaDoc command line parameters to declare them. Design Markers require no special version of JavaDoc and no special command line parameters.
- While meant for documentation, Design Markers, never the less, also allow test suites to verify design compliance by testing for the markers at runtime. For example, if certain return values from an API are supposed to be "consume only", then checking for "instanceof ConsumeOnly" can be added to those tests.
ExamplesAs a simple example of using Design Markers and illustrating the JavaDoc produced for them, I have placed four Java source files (Abelian.java, AddrType.java, Contract.java, and TypeSafeEnum.java) and all the JavaDoc that is generated for them (starting with index.html) at http://www.polyglotinc.com/designMarkerExample/ and they can be viewed and/or downloaded from there. Whether with JDK 1.3 or 1.4, the JavaDoc command that was used is simply "javadoc *.java".
About the AuthorAs principle consultant of PolyGlot, Inc., Bruce Wallace has provided consulting and custom computer software development services around the world. Projects have been completed in Sydney Australia, Perth West Australia, "Silicon Valley" California, "Route 128" Massachusetts, Austin Texas, and currently in Atlanta Georgia. Bruce has been developing with Java since 1996, Object Orientation since 1988, and Software Engineering since 1974. During his career, he has covered the full spectrum of roles from manual QA tester through CTO, even in organizations you've heard of like Apple Computer, Sun-Javasoft, Hewlett-Packard, Coca-Cola, and BellSouth. Bruce's first published article was way back in the May 1981 issue of Byte magazine, and his most recent was in the March 2001 issue of JavaPro magazine [http://www.polyglotinc.com/reflection.html]. ©Copyright, 2002-2003, PolyGlot, Inc.