This morning I read an article on what the ideal operating system should look like. I devoured all all three parts and it got me thinking about my thought process and how I approach development. This post is a loose collection of those thoughts.
One thing that I’ve discovered about my thought process is how I approach problems. Too many times, it’s easiest to start from where I am right now and how I can modify the existing tool / code / product to do what I need. This provides a good starting point for context of what’s immediately possible, but not for solving the problem.
For example, let’s consider the text editor. The main purpose of a text editor is writing things down. You want to be extremely good at that if you’re going to be an editor that people want to use. Based on this description you can build an editor that’s a joy to use and makes the process of getting information into the editor easy and intuitive. There’s a problem with it: what happens when a user is done with new document that they’ve created? My original description did not include anything about saving or exporting the documents that are created.
Realizing that you’ve left saving out as a feature, you might write up a job story that looks something like this:
When writing a story I want to ensure that it’s been saved so that I can share the saved document with other people.
If you start from where you are, you might think to add a Save feature and tie that to a menu item, a keyboard shortcut, and maybe even a toolbar to provide multiple options to your user. This is a valid concern, but it overlooks one key thing. The user doesn’t care about saving, they just want it saved.
The user’s job is to write, not to save something. Explicitly saving something is a task. User’s aren’t interested in performing a task unless they have to. Auto-save is what the user needs. At this point in the process the only thing they need to know is that their work is saved. Instead of focusing on the job at hand and how this feature supports that job, adding a Save feature focuses on the task.
I’ve fallen victim to thinking that focuses on the task instead of focusing on the overall job, but I guard against it now. This causes me to think differently than a lot of developers: rather than focus on fixing one particular thing, I focus on what the underlying (or overarching?) problem or job is. This means I talk past people sometimes because I forget that we’re talking about different things.
How to fix a problem
On a recent open source project that I work on I opened a pull request that introduces a new higher level concept to the project in the service of fixing one discrete bug. To me, the discrete bug was a manifestation of the lack of that higher level structure. Without that common vocabulary, different parts of the code were touched by different developers at different times and there was a discrepancy between how the concept was represented.
To me, that larger problem was what needed fixing. To other developers, the bug needed fixing. Thinking about that larger problem, I tackled that and fixed the bug. Another developer on the project focused on the explicit problem and added the one-line fix to that code path that solved that one bug that manifested itself. On the surface, the one-line fix seems simpler because less code was involved (my fix was a little more than 30 lines). The one-line solution was only simpler when viewed as the task “fix this bug” not “fix the problem that gave rise to this bug.”
To be fair, both are legitimate ways to approach the problem. The one-line fix that focuses on the task at hand fixes the bug and avoids possible over-engineering that might happen by thinking about the bigger picture. It also runs the risk of having the same problem solved in different ways throughout the code base as each “just one-line” fix adds another branch into the complexity of the program.
Thinking like a developer vs like a designer
This all ties back to the story that started this post because of the way the problem was approached. Most developers I know would balk at the idea of creating an operating system, then starting by removing the file system and applications. “But where will I store my files and how will access them?!” I hear them all exclaim at once. Most designers I know would hear that idea, think for a second, then say “ok, so what replaces it?” followed closely by “and what was the user trying to do when they accessed those files?”
Designers tend to think in terms of solutions to general problems. Developers tend to think in terms of solutions to explicit problems. This is still a nascent revelation to me, but starts to explain to me while I’ve always felt slightly out of place in the development world.
It’s also making me question my description: am I still a developer with a bit of design knowledge or a designer that happens to program?