Design
Doing various online courses to help my software design skills, I’ve encountered the same basic ideas in various guises: there’s the 6 step recipe in How to design Programs:
- From Problem Analysis to Data Definitions
- Signature, Purpose Statement, Header
- Functional Examples
- Function Template
- Function Definition
- Testing
Step 1 encourages Domain-Driven Design (DDD): once we’re clear on the data definition, we know the signature. The signature in turn tells us which function templates to use — also known as Design Patterns, of wich there are 23 according to the classics.
Since the data definition, signature and template are so closely related, it’s easiest to think of them as a table of parallel rather than consecutive steps:
Data Definition | Signature | Template |
---|---|---|
Atomic | ||
Structure-type | ||
Fixed-Size | itemization | |
Arbitrarily Large | self-referential | natural recursion |
Intertwined | mutual references | nested lists |
The How To Design Programs’ recipe is a form of Agile’s Test-Driven Development in that the first step after deciding the Data Definition (from which we then know the signature and in turn template or pattern) is to write an example. To be able to run an initial failing test we need a stub, called a header in the recipe’s jargon. This gives us our first test.
The header (aka stub) is given it’s shape by cutting and pasting in an abstract skeleton for its signature, and the function definition step sees this crafted into working code which passes the test. The header gets overwritten by the template, which gets edited into the function definition, which gets polished through testing, so these can all be grouped into code.
Example | Code | Test |
---|
In instructional design, there’s the 5 steps in ADDIE, an acronym for Analysis, Design, Development, Implementation, Evaluation.
Back in 1944 maths professor George Polya wrote a book called How to solve it which I’m summarising in these notes because I think his 4 steps covered the above most succinctly and literately:
- Understanding the problem
- Devising a plan
- Carrying out the plan
- Looking back
Polya’s book is organised as an alphabetical glossary, and introduced me to an ancient Greek mathematician I’d never heard of before, Pappus, who back in around 300 AD introduced the importance of working from the goal (aka solution) backwards. This was the original definition of the word analysis as opposed to synthesis. The modern meaning of analysis tends to breaking things down into their atomic parts whereas synthesis is seen as building molecules from atoms, whereas the original meaning was working backwards vs exploring forwards.
1. Understanding the problem
Polya’s advice is to start thinking with a pencil. “Draw a figure. Introduce suitable notation. Separate the various parts of the condition. Could you write them down?”
A reason I’m teaching myself Hugo is the frustration with the documentation systems which come with various programing languages. The worst documented part of most programing languages is their documentation system. Considering the importance of “thinking by writing”, learning the documentation system of a programing language should be the first step, but tends to be covered in the final chapter in most manuals.
Once you understand the problem, you can work backwards.
A fool looks to the beginning, a wise man regards the end.
Polya reverses that to:
A wise man begins in the end, a fool ends in the beginning.