Only a few high-level UML diagrams survive the life cycle of the application
We need models to represent the software design. But even in large projects of about 500 man-months, I observed that only 3-4 sequence diagrams really matter and have a chance of surviving the entire life cycle of the application. Those 3-4 sequence diagrams (and class diagrams that represent their static time relationships), usually represent the high level design of the application.
Or, look at it this way:
Any decent enterprise application will not have 20 generic call flows. There will be one or two generic (or abstract) call flows, which all the concrete use cases implement. Let us take a simple Struts / EJB application. The generic flow will be something like - an action class calling a validator and then calling a stateless session bean, which in turn calls a domain class, which will call a DAO. All the use cases of the application just implement this flow with concrete classes that are specific to that use case.
Do you agree?
If you do not, I would like to hear about applications that have 20 different generic call flows and survived for 5 years after the first release.
If you agree with me, we are boiling down to 3-4 class and sequence diagrams even for large enterprise applications comprising several thousand classes.
It is hard to find good UML documentation that is kept in sync with the evolving code
You might say that in addition to the few high-level diagrams, you want to document all the use cases of the system for training or documentation purposes. During my 15 years of experience in the enterprise software world, I don't remember seeing well 'maintained' UML documentation ever. First of all, good diagrams are difficult to produce and are not found that often. Secondly, they are out of sync with the code most of the time. Most of my experience is with large banks, insurance companies, Auto companies, etc. Those environments are just too hectic and their resources are limited (difficult to believe, but true) for 'maintaining' good documentation.
So am I suggesting that we get rid of UML?
No. We need visual models to represent complex systems. Human brains are at their best when processing visuals.
So what is a reasonable solution to easily produce and maintain UML models?
- Start with drawing high level diagrams on paper or whiteboard for the generic call flows. These diagrams should not exceed 3 or 4 even for large applications.
- After these diagrams are stable, you might use the UML drawing tools. Or just scan the hand drawn tools and make them easily accessible to everyone in the team.
- For the diagrams at the next level of abstraction (any useful models should have different levels of abstraction), generate the UML from source code or at runtime. You can generate both class and sequence diagrams using both methods.
- If you hate drawing the diagrams, simply write the code for the shell classes and generate the high-level UML class and sequence diagrams as well. This way there won’t be any UML to maintain at all.
The source code is the truth - generate the UML from the code
Can you argue against the statement that the code is the truth? If you do not, why not generate the models from the source code itself? I am not suggesting the round-trip engineering, by the way. I am just suggesting a one way trip - from code to models.
Problems with the generated UML
Problems with generating the class diagrams: When we hand draw a class diagram, we show the relations between the classes involved in a use case. Most existing class diagram generating tools allow the user to drop the Java classes (the source code) into the tool and the tool automatically shows the relations between the classes. The problem with this approach is, how does one know about the classes involved in a use case to begin with?
The tools that generate the UML diagrams at runtime can solve this problem by first capturing all the classes participating in a use case and then generating the class diagram showing the relations between those classes only.
Problems with generating the sequence diagrams: Sequence diagrams by definition show the runtime relationships between the classes in a use case. Static sequence diagrams generated from the source code can never show the interactions between the concrete classes at runtime.
The tools that generate the rutime sequence diagrams solve this problem by capturing the concrete classes called at runtime. However, the generated sequence diagrams can become verbose and defeat the very purpose of models, which is to highlight the important design aspects and filter out the unimportant details.
Choose the tools that offer the necessary filtering mechanisms to view the generated diagrams at different levels of abstractions. When debugging a defect, you may want to see the low level interactions in a particular tier of the application. On the other hand, some times you may just want to find out all the important business classes called in a use case. Good tools should allow you to cature the runtime interactions for a use case and apply different filters on the same sequence diagram to view it at both high and low levels of detail as necessary.
In this age of agile development, it will be costly to spend time on drawing UML diagrams. Generating UML diagrams on the fly as they are needed would save the time to produce the diagrams and also keep the diagrams always in sync with the source code.