I’m always looking for nice little mnemonics to help out remember the important concepts in design. Here’s one for model-driven development I call the “Seven C’s”. It basically enumerates the seven stages a design goes through, from initial idea to code.
The Concept phase is about understanding the problem. In other words: requirements analysis. When you’re in Concept mode your main focus is on validation – am I solving the right problem for my customer?
In Creation mode you are synthesising a solution. At this stage we are building an Ideal model, ignoring many of the complications of the real world. Our design should be completely concurrent (every object has its own thread of control), completely asynchronous (messaging) and completely flat (no hierarchy)
Your focus should be on:
- Design verification – if I can’t demonstrate an ideal design works then there’s no way a less-than-ideal design will work!
- Design evaluation – as with all design: is this the best compromise?
Also known as ‘design levelling’ (but that doesn’t start with C!). Your Ideal model probably has some high-level elements (components, etc) that need further refinement; and plenty of low-level elements (objects) that can be collected together to perform ‘emergent’ behaviours. Design levelling is the act of (re)organising the design into appropriate levels of abstraction – sub-systems, components, objects, etc.
Our Ideal model treats every element as concurrent, but experience tells us that isn’t practical for a real software system, so reduce the number of concurrent elements in our system to get the most effective solution with the smallest number of threads.
Like any other construction project our plans must contain enough information so that skilled implementers can build our dream. In our case the construction plans are our class diagrams, composite structures, state machines and algorithm descriptions.
Once in the construction stage our focus is on verification – doesn’t this design still fulfil its requirements?
Our construction models may be complete and may be translatable directly to code. However, the result of that translation may not be ideal; and may not benefit from many of the features of our chosen implementation language. Corruption is the act of modifying our design to make the most effective use of our implementation language and platform.
The end result.
How does this all map onto typical model-driven-design nomenclature? Well, pretty much like this:
Computationally-Independent Model (CIM)
Platform-Independent Model (PIM)
Platform-Specific Model (PSM)
* Apologies to all the grammar fanatics out there for my use of the “grocer’s apostrophe”
- Practice makes perfect, part 3 – Idiomatic kata - February 27, 2020
- Practice makes perfect, part 2– foundation kata - February 13, 2020
- Practice makes perfect, part 1 – Code kata - January 30, 2020
Glennan is an embedded systems and software engineer with over 20 years experience, mostly in high-integrity systems for the defence and aerospace industry.
He specialises in C++, UML, software modelling, Systems Engineering and process development.
However, how about also an 8th "C" which is "CONFIRMATION" - confirming that all the other things have done what you intended them to do?
Also, is Code really the end result? A working system? A happy customer? Where does design end?
I'll give you CONFIRMATION; and let's add CONTENTMENT for our happy customer! 🙂
Of course, you're absolutely right: design doesn't end with code. I think any good design process doesn't separate requirements from design from code from test. They are all aspects of one whole.
If we take each C as a design level of abstraction - that is, a focus for our effort; or the thing we're concentrating on at this stage in the design - then, properly, we should be defining methodologies for synthesis, verification and validation for each level. That is:
What techniques/methods/guidelines/rules should we be using when creating new elements?
What techniques should we be using to demonstrate our design is compliant with / traceable to its requirements? And how can we test that the system has been correctly implemented with respect to the focus of attention at this level?
What methodologies (etc.) are we using to ensure we have evaluated our design against the project's stakeholders' needs, our intrinsic quality desiderata, etc?
As you progress through the stages of design/development your emphasis will shift between these methodologies, with one or two becoming more your focus than the other(s):
The emphasis at this stage is primarily on validation - ensuring we have the correct set of requirements; and verification - demonstrating compliance to these requirements. There should be no invention or synthesis at this stage.
As the name implies, synthesis is the main focus. Although the design must (obviously) be demonstrated to meet the requirements it is the validation - the evaluation - of the design that should take precedence at this stage.
COMPOSITION, CONCURRENCY, CONSTRUCTION
At this stage I would expect a markedly decreased emphasis on synthesis - the guidelines become more about how to modify the design, rather than how to create a design. The major impetus should be on verification - from an integration testing perspective, and also from a design verification perspective - ensuring changes to the design don't affect its ability to fulfil the system's requirements.
CORRUPTION AND CODE
By this point there should be very little (if any) new design performed. The focus should be on verification - ensuring and demonstrating that the system is being implemented correctly with few latent faults. Validation should be limited to ensuring our corruption choices are valid.