Sunday, March 25, 2007
Design: lean, but upfront
What is remarkable about this project is that the design model bears very little resemblance to the analysis model. This should not come as a surprise: the analysis and design models are created for different reasons, with different goals, and shaped by different forces.
The analysis model (or, more appropriately in this case, the problem domain model) is created to encode our understanding of the problem domain. Therefore, major goals are the accuracy, a sufficient completeness, close adoption of problem domain terminology. We need a strong focus on capturing essential complexity and on leaving outside any accidental complexity; as part of this, we need to focus on keeping any element of possible solutions out of the way.
The design model is created to reason about a "good" solution, where "good" can be informally defined as "solving the problem while maintaining the right balance among all the non-functional requirements, the various design principles, all the non-technical issues like who's gonna implement the different portions of the system, and so on".
In this case, we had some large uncertainties, as some business rules were not crystal-clear, some subsystems with which we should integrate were not finished yet, and so on (business as usual). However, we agreed that the underlying domain was relatively stable, so we expect that after an initial instability, our system will be relatively stable. Therefore, there was no need to push the envelope on extendibility.
However, there was a lot to gain by moving to a meta-level description of some domain objects. A lot of structural properties could be easily captured that way, avoiding the creation of several custom classes to represent domain object. Also, by trying to move to a meta-level description, we gained a better understanding of some non-trivial, history-related issues (it's not unusual for design to clarify some analysis problems). We didn't try to capture behaviour at meta-level: instead, we defined a few hot-spots where behaviour can be easily plugged. The nice part is that in the end most classes will be very small, behavioral plug-ins will have a single concern and will be easy to develop and test without having a complete knowledge of the system (this will certainly help as the implementation will be offshored).
Now, what about those analysis models? Has the time spent on those diagram been wasted? I believe the time spent on those model has been very well spent. They helped the project leader keeping track of his understanding of the problem. More than that, the knowledge encoded in those diagram can be quickly shared with others. I didn't do any analysis: I've been given the models, and I've been asked to participate into the design. Sure, I knew some of those concepts from previous experience, but reading the models helped a lot, in a short time. I expect anyone new to the project will get acquainted more easily by reading models that are very close to reality (while the design models are, in this case, more about a meta-reality).
Looking at the design models, it's hard to say that you could get there starting with a trivial design (most likely, closely inspired by the analysis models, or even by a small portion of them, informally captured as nouns in some use case or user's story) and working your way out by refactoring. The architectural difference is too big. With a strong focus on code, it's hard to see the forest for the trees. You'll end up with an accidental architecture (or accidental structure, as I like to call it) instead of an intentional architecture. But that's the usual debate. What is interesting in this case is that we did very little overengineering to protect ourselves from change. Actually, we did almost nothing: the same behavioral hot-spots that we used to complete the meta-description are also perfect for extending or changing behaviour at a fine granularity. We designed the system for simplicity, high decoupling between classes, good separation of concerns, adequate performance, simple piecemeal implementation. Several other good properties just followed. So this is not the dreaded "big upfront design out of fear of change". Indeed the investment in design has been a small fraction of the total development effort: but as any good investment, I think it's gonna pay off big dividends.



