Shame on you all that I had to add this page on 7th March 2003!
is a relatively old technique of SoftwareDesign
that has been successfully used in a wide range of StructuredProgramming
environments and languages. It is the procedural (step-by-step) form of SeparationOfConcerns
and has what some may call a fractal nature of task division.
The principle of StepwiseRefinement
kind of tries to roll-up YouArentGonnaNeedIt
in one and most programmers (at least the GoodProgrammer
s I've encountered) tend to use StepwiseRefinement
The software design is approached as being a series of layers of modules of decreasing abstraction with call flows typically forming hierarchies through the modules. You start by identifying the top of the hierarchy (essentially main() or do_stuff()) and then apply TopDown
design to work out the next set of modules that need to be built/written.
can (and often is) also applied even down to the function level in languages such as CeeLanguage
For example, the top level might be the function main(). The SoftwareEngineer
decides that main needs to call foo() and bar(), so she writes the function main() to call foo() and bar() but leaves foo() and bar() stubbed out with printf's. She then runs her UnitTest
s and confirms that foo() and bar() are called correctly i.e. we get printfs coming out where expected, so main() works. She then implements foo() which is straightforward, and runs the UnitTest
s once more to verify that both main() and foo() operate together correctly. She then goes back to look at bar() but realizes that bar() needs another lower level function, baz() to work. So, she implements bar() to call baz() but again just leaves baz() stubbed out. Once more the UnitTest
s are run to confirm that the software works correctly. The final stage is then to implement baz() and finished checking the software with the UnitTest
The advantage of StepwiseRefinement
is that it allows for IncrementalDevelopment
but on a much finer level of granularity. A little bit like BarryBoehm
. It also uses UnitTest
s as an integral feature of the development process. The software is also rapidly built as StepwiseRefinement
lends itself naturally to producing working (and tested) prototypes of the software as it develops, and it is often possible to build prototypes in remarkably short periods of time as you can apply YAGNI pretty much down to the function level. StepwiseRefinement
is highly scalable, as large systems can be developed in a structured and predictable fashion from it.
The downside is that StepwiseRefinement
is open to interpretation of precisely what abstraction functions are required at the higher levels. This generates a tendency towards an architecture that has one larger high-level module with several smaller "worker" modules below it. That is, the hierarchy tends to grow across rather than down (which is the intention).
I'd be interested to hear anyone else's thoughts on this. Having been programming CeeLanguage
for a few years now (after being a JavaLanguage
person for 2 years) I have become quite fond of StepwiseRefinement
and really do wonder how people program without it, especially when using StructuredProgramming
If you feel the need, PleaseComment
- Brush Teeth
- find toothbrush
- find toothpaste tube
- open toothpaste tube
- Put thumb and pointer finger on cap
- turn fingers counter-clockwise
- repeat prior step until cap falls off
- squeeze tube onto toothbrush
- clean teeth
- put brush on teeth
- move back and fourth vigorously
- repeat above step 100 times
- clean up
- rinse brush
- turn on water
- put head of brush under running water for 30 seconds
- turn off water
- put cap back on toothpaste
- put all items back in cabinet
often leads to a solution where each module represents one part of the task in chronological terms, which can lead to multiple modules knowing the details of some data structures. See DavidParnas
' wonderful paper OnDecomposingSystems
for examples of different ways to decompose a system, some of which are more robust against changes in data representation.
I don't see wrapping data structures and StepwiseRefinement to be mutually exclusive. DavidParnas paper is flawed in some ways.
They aren't, but it takes care to do both at the same time. The point is that it's very easy to think of the "steps" in StepwiseRefinement
as being "steps to solve the problem", which tend to be chronological. For example, if the above "brushing your teeth" system were implemented naively, it would be natural to have subroutines for each line, called by the next higher level and calling the ones at the next lower level, all of which have knowledge of the "toothbrush" and "toothpaste" data structures.
Please explain "which have knowledge"? Perhaps this is related to DatabaseNotMoreGlobalThanClasses.
As far as subroutines, yes in practice one often does such. The above illustrates the design dividing process, not the coding and repetition factoring.
Stepwise Refinement and Deviation Management
"Dealing with Deviations from Framework" under HelpersInsteadOfWrappers
illustrates how to use the levels to go lower into the StepwiseRefinement
tree to "override" behavior for custom exceptions-to-the-rule, but still potentially use some of the existing branches. -t
See also: ProceduralMethodologies