Lessons from design patterns

We can learn a lot from the history of design patterns. The works of Christopher Alexander contain many lessons, and the history of design patterns in software should be heeded for fear of repeating similar mistakes with any new technology. So, in this section, I would like to remind you of or bring your attention to some lessons we could learn.

Use patterns at the architectural level

We know software architecture is not easy. Let’s push to recognise that. Wherever you sit in the hierarchy, remind people that architecture can be wrong and fixing it is an option. Change is routine, and refactoring to patterns is expected at all levels.

Remind everyone that architecture is the idiom of the whole. It is only by accident, consensus, or dictate that any software is built the way it is. Software architecture and team communication modes mirror each other, and most of the development cost comes from communication overhead and delayed decision-making.

Mock-ups and prototypes are essential

An application needs a mock-up stage. This isn’t up for debate if you want to develop good software. You can create something small or one-off without a prototype, but anything built to last for a while and of sufficient complexity needs an exploration phase.

Developers use wireframes to create examples of application UIs. These examples allow developers to review UX ahead of prototype development. Software developers couldn’t use these approaches in the past, but recently, there has been an increase in software support for making high-quality, even interactive, mock-ups. The quality of UIs has grown in response. This is proof enough for me that UI is edging closer to a solvable problem, even if UX is still far from it.

Beyond UI, people develop in quicker languages before re-writing or migrating the poorly performing parts. This is how we end up with Python-based prototypes and C++ or C# final versions of applications. Python allows for a cardboard cut-out version of the final app.

When you omit the mock-up stage, you miss out on making big decisions early. As mentioned before, when you make decisions late, you make everything late. Independent programmers often get caught up in making the software functional first, ignoring the design stage, more so now because we often misinterpret the Agile Manifesto[AM01] as suggesting we should refrain from any upfront design. What is the cost of doing this, though? What are the real problems with building first, then deciding how it should be modified?

We’ve moved away from the ‘big-design-up-front’ approach and embraced a more hands-on set of processes. We iterate on our designs until an acceptable final form is found. This works exceedingly well when the target audience is well-known or well-understood by the developers controlling the creation process. When the customer is less well understood, a product owner stands in for understanding the values of the end user. But this leads to developers having ideas of what will make a good system without solid evidence, either to the affirmative or the contrary.

Guesses can be wrong. This is obvious. But what might not be so obvious is how often they can be right in an information-rich environment. What might be ambiguous or unknowable early in development becomes obvious and known much later. We know there are times when developers can be right and be sure they are right. But if these only come at the expense of working through the project from start to finish, then we are living in a horrible fated world of pain and suffering for every developer. However, we know this is untrue. Well, apart from those who choose to write in C++. The decisions we must make before the end of the project can be made much nearer the beginning when we actively engage in mock-ups.

Christopher Alexander almost always produced large, 1:1 scale mock-ups of elements he intended to bring into the world to have a better chance to make decisions as early and accurately as possible1. He could be found making two or three-storey cardboard cut-out structures to make sure the colour and shape were suitable for a situation. I imagine many architects smirking over the idea of building a prototype of such scale and convincing themselves Alexander was not a capable enough visualiser to design without these crutches. But none of them ever made anything as cohesive and wholesome as he produced on a regular basis. His buildings all have a settled air of suitability to the environment and the users of the building. Many structures by other architects try to accommodate one or the other in favour of getting a building put up. But that’s the same approach as the developer who works on the functional side first and the UX second.

If Christopher Alexander could make and use massive cardboard cut-outs to allow him to make his decisions earlier and produce much more wholesome constructions, then why don’t others do it too? Part of the answer lies in misunderstanding the purpose of prototypes and mock-ups.

Many developers, both structural and software, think of prototypes as static examples of the final form. They are not. They are not pictures of a goal; they are stand-ins for the goal that we can test in much the same way as the final piece. These stand-ins introduce many more parts of the final context needed to make the right decisions. An image does not help you identify where the sun will shine at each part of the day, which rooms can see other rooms, or whether you can hear someone three doors away. An image of a device will not tell you whether an item seems small when held in the hand or feels right when it reacts to touch or button presses. The best example of this for computing is the story of the wooden2 Palm Pilot prototypes.

The other misunderstanding about mock-ups’ purpose is their capacity to raise awareness of relational issues or collaboration in spaces. Mock-ups include the possibility of validating interactions.

Without being brought together, individual mock-ups show the edges between elements but cannot show interactions. They help show where styles and interactions might occur but don’t reveal system-wide interactions.

For example, a 1:10th scale model of a building will expose more than a map because it will show how different elements work in three-dimensional space. It might show how high the windows are compared to the surrounding landscape, allowing you to judge the view somewhat. The model could be used to deduce whether the building would cast a large shadow across an area. The shadow of a roof reduces the loveliness of a conservatory. Using a scale model, we can avoid the mistake and find a new location before the first brick arrives on site.

Things like inclines become easier to estimate, and shapes are easier to scale up rather than visualise from a plan view. Without being aware of the slope, you may not know to ask the developer to include steps in the path design, necessitating outdoor lighting for fear of tripping. The chain of effects of every realisation can be long, so it’s always worth mocking up early to bring these considerations to the fore.

But when you don’t mock-up, you leave all these realisations until later. The need for four button presses before hearing the track you want reduces the immediacy of your music app. But you only feel the impact once you build it. Bringing the product image up in a modal window might have been a good idea, or opening the gallery on a new screen might have been better. Without a mock-up, you complete the work before your decision can be an informed one. Like in building construction, a mock-up will help tease out the questions and worries before they become problematic.

In software built to present a fictitious world, the content designers create a world where users navigate the space. The space itself is part of the design, much like the guest flow design of theme parks and paths through some furniture stores. To be sure to get this spatial design right, the designers could build the current plan and evaluate it before tearing it down and trying a few more arrangements. They could, but they don’t. They mock, grey-box, and arrange on a model or test with pieces of paper on a table. Whatever they do, they do it quickly and without involving software developers, gardeners, carpenters, or a furniture arranging crew.

When you don’t use mock-ups in your development, you build something that would match your first mock-up. In effect, you are making a very expensive mock-up. You will want to change it but will feel invested. It will feel difficult to say anything. If you don’t say anything, a competitor will have an easy time leap-frogging your attempt. They will be wiser from your mistakes.

Don’t omit the mock-up stage. Prototypes aren’t an extra expense. Mock-ups are not optional. The only decision you can make is how expensive you let them be. If you don’t decide, they tend to use up your whole production budget.

Mock everything. Mock software and sites. Mock books and workspaces. Mock organisations and teams and customers. Every decision is easier to make when you have the power to visualise the structure about which you are making the decision. Every decision is easier when you can think clearly about the relationships between things in their final home.

Patterns are an emergent property of something more fundamental

We must also learn to continue the research. Christopher Alexander did not stop when he developed the process of simplifying complex construction in Notes on the Synthesis of Form. Instead, he went on to produce A Pattern Language. From there, he did not stand still either, instead developing an even deeper understanding of patterns and their origin by discovering the 15 fundamental properties of forms. The programming pattern movement stagnated in this respect, not moving on to finding fundamental properties of anything so far. We should continue our work.

For Christopher Alexander, the properties reflected repeatedly encountered instances of a class of action in space and time, like fractal recursions on itself. Iteration of action, not a specific action and not an outcome. Application of one of a selection of transformations, not the result.

The patterns in A Pattern Language were named. In The Nature of Order, there were 15 types of unfolding in a context. If we return to the GoF book[GoF94] patterns, we find unfolding along the lines of nominalisation, aggregation, and wrapping. The contexts are ‘needed variation’ or ‘unification of the disparate’, but what else? Storage? Robustness? Remoteness? Verification?

So, we need to look at the patterns and pattern languages we have in software development, find the places to make our incisions, the lines between the domains, as Christopher Alexander did with architecture and colour, and inspect the patterns in those domains to see if we can find any fundamental forms to help us define a more straightforward unfolding process in each of them.

1

In [NoO4-04] from page 287, he reveals how the West Dean Visitor Centre was constructed with attention to subtle details only visible when using large mock-ups. In much earlier work, he suggests using wooden constructions to be more easily adjusted until just right[TTWoB79], or in [TPoH85] in the ‘Postscript on Color’ where mock-ups were used to identify just the right amount of yellow and green to mix in to make the building colours perfect.

2

It was literally a piece of wood with a printed version of the UI pasted to the front. A quick web search will find the whole story and possibly change your mind.