Article summary
I’ve been looking for innovative ways that design thinking might be applied to software development at the level of writing code. Already, our software development process is imbued with design principles, but what about when the text editors are open and individual functions and objects are being named and composed? What makes for good code design?
Not long ago, I had what (at first) seemed like a breakthrough. I thought something like this: “If design is about serving the needs of people, then at the level of code, we have requirements that need to be fulfilled for end users, but also requirements that must be fulfilled to satisfy interfaces for other components of the system. We can consider the components of a software system as similar stakeholders at the local level, with their own requirements to account for in our design process. In this microcosm then, maybe the interfaces of these other components stand in for the people.”
Losing the Human Element
I asked Kedron (an Atomic designer) to lunch to discuss. As we talked, it became clear that I had missed something very important. By having interfaces “stand in” for people, I had eliminated the human element. I had come up with a clever mapping of one problem-solving model (Design) onto another (Engineering), but it was only a partial map. Essential properties of the human element were lost in translation. You might be able to satisfy an interface’s implicit (or explict) contract, but you can’t empathize with an interface.
By focusing only on the requirements resulting from people’s needs, I had turned a design problem into an engineering problem. Both are valid problem solving approaches, but I had confused one for another.
How was it that I had made such an error in the first place? After some reflection, I was struck by the irony inherent in my misconception. I realized that I had missed the mark with my mapping due to the very myopia that design thinking seeks to overcome. I had failed to approach the problem through the lens of a designer — I had failed to empathize with that perspective. I had projected my own perspective onto the problem to such a degree that it was impossible for me to see what I lacked from another perspective.
“Empathy is probably the single most important difference between a good hacker and a great one. Some hackers are quite smart, but when it comes to empathy are practically solipsists. It’s hard for such people to design great software, because they can’t see things from the user’s point of view.”
– Paul Graham, Hackers and Painters
Code Is for People
So is there such a thing as good code design, or is there only well-engineered code? Is my project a failure? Not at all! Now that I recognize my mistake and know that the human element and empathy are essential to design, not only will I be more cognizant of the need for empathy in the future, but I already see several avenues where it might be applied.
Perhaps the first point to consider is that even code refinements like refactoring have an impact on our ability to deliver value to end users in the long run. The shared vocabulary and abstractions built up and honed over the course of a project either help or hinder the programmer in their efforts to create functionality for the end user.
“The most important property of a program is whether it accomplishes the intention of its user.”
– C.A.R. Hoare
Another thing to keep in mind is that there is at least one person who is immanently present to the code — the person writing it and reading it.
“Programs must be written for people to read, and only incidentally for machines to execute.”
– Hal Abelson, Structure and Interpretation of Computer Programs
“The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly. A programmer is ideally an essayist who works with traditional aesthetic and literary forms as well as mathematical concepts, to communicate the way that an algorithm works and to convince a reader that the results will be correct.”
– Donald E. Knuth, Selected Papers on Computer Science
- What is the problem we’re trying to solve?
- Who are we solving this problem for?
- What are the constraints?
Don’t forget that Who.