I’ve been thinking a lot about backfit explanations recently. It seems to me we (humans) do this an awful lot. I find it particularly amusing when I listen to someone justify something ex post, completely oblivious to what they are doing (no doubt I do this myself). I began to consider the standard description of the design process, particularly in software.
Now perhaps I lack foresight, but if I am asked to work on a feature with any semblance of complexity (i.e. where an upfront design session is required), then the following model almost never holds:
Design -> Implementation
What happens for me is something more like this:
Design (a bit) -> Get bored of just design -> Implement a bit -> Realise design is wrong -> Redesign -> Implement some more…
And so on. What this really represents is a repetitive process, a tight feedback loop that has been denigrated by some as primitive:
Trial -> Error -> Trial -> Error -> Trial…
I don’t think there is anything new in this; Agile was essentially a realisation that solutions of some complexity cannot be solved by upfront design. The feedback loop is too long; the proverbial (software) engineer is generally incapable of designing the right thing without giving it a go first. But the way we talk about design, particularly after the fact, it comes across as this isolated, directed process we do in advance of implementation. Whether or not one would accept this upon inspection is beside the point: it is clear that how design is spoken about differs from how it is actually done. Our theory-in-use differs from our espoused theory.
Learning is always about action… I may profess a view that people are basically trustworthy. But I never lend friends money and jealously guard all my possessions. Obviously, my theory-in-use, my deeper mental model, differs from my espoused theory. – Peter Senge
It is important to recognise our inability to know the right design upfront because from such a position of humility we can build systems that are adapatable. When we accept that we do not know what the future holds, that our design today could well prove inappropriate tomorrow, we build in a way to cope with such changes. Trial and error is not the inferior methodology it has been painted as, it is the appropriate incremental process: Scrum sprints are trial and error at the project level.
When we set up a tight feedback loop between (some) design and tinkering for implementation, we create the environment for surprising solutions to emerge. When we constrain these non-linear processes into a linear model, we preclude such emergence.