The programmer was viewed as the weak link in the development process chain. The software development process was the scaffolding put up to minimize coding errors. While this may still be true in some settings, Agile development has moved the needle towards the view of the programmer as an artisan/practitioner.
The Clean Room process was created by Dr. Harlan Mills from IBM. Dr. Mills' description of the process can be found in this 1987 article in IEEE Software: Cleanroom Software Engineering.
The driving idea behind the Clean Room process was that software was to be produced by a series of correctness-preserving steps. So if there as an error produced in the software, the process step that produced the error was changed so that error could not longer be produced, then the process was re-run. The software was never 'fixed'. The process was 'fixed'. In a strict version of the process, the coder never compiled the code. That was part of the testing group's effort. If the code did not compile, it was determined how code was generated that did not compile. The code would then be thrown out, and the process would be re-run to allow the 'coder' to generate new code using a new process step(s) that would not produce the uncompile-able code.
At the core of the original Clean Room was something called Box Structured Development. It is partially described in: Box-Structured Requirement Determination Methods. It would take one or more blog entries to completely go through box-structured analysis and design, but here's a section from 'Box-Structured Requirement Determination' to give a feel for what happens:
Requirements gathering procedure
Step 1: Identify Inputs - Via information gathering tasks, a list of system inputs is generated. It should be recognized that these inputs will be at various levels of abstraction, from databases and files to simple data variables and physical signals (e.g., a clock pulse). All potential and available inputs should be listed. An analysis of the necessity and sufficiency of the inputs will be performed later. We define the list of inputs as ]= (11, 12 .... ,Ii).
Step 2: Identify Outputs - A list of required outputs from the system is generated. Close interaction with the customer and users is needed to develop a complete output list. The output list is defined as 0 = (01, 0 2, .... Form Black Box Transactions - The black box behaviors that relate the input history to the required outputs are described. A set of black box transactions is generated, (Pl, P2, ...,Pk). Each transaction is a function from the input history to a set of required outputs, i.e., pro(I*) O m where O" c O. All required outputs must be produced by one or more transactions.
End of requirements gathering procedure.
Once requirements gathering is complete, a black box hierarchy is created by refinement of the initial black boxes into lower-level black boxes until 'code' is reached. Each black box is decomposed into a triple of (another) black-box : state-box : clear-box. The clear-box defines the black-box at the next level of iteration.
Example Clear Boxes |
To my knowledge, there were never many projects that attempted this process. The one usually touted was part of the IBM CICS project. What really killed this approach to development was the fact that no self-respecting coder wanted to submit themselves to this. It conjures up images of the human computers Richard Feynman assembled during the Manhattan Project. However, one could imagine tools being built that automatically converted high-level problem statements into box-structured statements and then into code.
Completely top-down development processes (where the solution is some sequence of iterations from the requirements) always has the problem that the structure of the requirements imposes itself on the solution - which is probably not optimal. Top-down solutions that only tag the fulfillment of a requirement(s) design/code artifacts allows the structure of the solution to differ from the structure of the requirements and follow, say, design patterns or structure imposed by the solution platform.
So how is this the ultimate structured development process? Well, it takes practically all development decisions away from the coder and distributes them between the requirements and design engineers. It also targets the process itself as the source of bugs. If you have followed my other posts, you know I make a distinction between projects that must be 'good' and projects that must be 'right'. This process assumes all projects must be 'right'. So arguably, this fulfills the dream of structured development.