Thursday 6 August 2015

Coding with empathy

Coding with empathy

Amanda Glosson explores what we can gain by putting ourselves in someone else’s shoes

Empathy is defined as the ability to understand and share the feelings of another. If I were to relate a story to you and ask you to empathise with me, I might say something like, ‘Imagine yourself in my shoes’. But if you were to follow these instructions, you would only be part of the way there. Empathy isn’t imagining yourself in my situation. Empathy is imagining what it’s like for me to be in my situation.


Our difficulty in imagining what it’s like to be another person and to empathise with them has a lot to do with how much context we share. As a frontend developer, it’s much easier for me to empathise with someone struggling with email templates than to empathise with someone struggling with multithreading. I have many more points of reference, a context that overlaps more with the first person than with the second.

This certainly doesn’t make empathising with the person struggling with multithreading less important, it just means I’m going to have to put a bit more work into imagining what it’s like to be them in their situation. It will require more empathising on my part to bridge those gaps in understanding.

WHO?


As developers, we should be empathising with those building email templates and those multithreading in Java, but who else should we be empathising with? We should be empathising with those affected by the code we produce. These people can be broken down into three groups: our teammates, our code consumers, and our end users.

Our teammates are typically the smallest group, but the group of people most affected by the code we write. When solving problems, this group will usually have a context that’s much closer to our own, making it simpler for us to write code that they will be able to work with easily. If we miss the mark here, this group will have the opportunity to ask us questions and give us constructive feedback.

Our code consumers are the people who build on top of the code we build. For example: perhaps we work on a JavaScript framework and other developers use this framework to build other services and end products. There shouldn’t be any expectation here that these consumers will have a context that overlaps ours. Instead of being able to easily ask us questions or give us immediate feedback, this group might only have our code and its supporting documentation to indicate the problems that we’re trying to solve.

The final group of people affected by our code is our end users. These are the people using applications that we (or those consuming our code) have built. This is typically the largest group of people that we will affect with our code, and they probably share the least amount of context with us. While these users will probably never see the code we’ve written, and thus are outside the scope of this discussion, we do need to consider how the code we write can help the integration of features, including – but not limited to – full accessibility and perceived performance.

All of these groups will exist, regardless of the scale of the projects we’re working on – from solo weekend hacks to projects involving hundreds of other developers and spanning multiple years. At any point in time we may find ourselves affected by our own code as a member of one or all three of these groups.

WHY?


Are there reasons to empathise with those affected by our code, outside of generally exhibiting goodwill towards one another? Is empathy important to the practice of software engineering – and, if so, why?

I do think that at some point civilisation will look back and laugh about how we fill buildings with people who sit and talk to computers all day, but until then we still have some big problems to be solved. And we need teams of people with diverse backgrounds and knowledge, teams with small amounts of shared context, to come together and solve them.

One of the biggest challenges these teams will have to overcome is naming. Phil Karlton is credited with saying: “There are two hard things in computer science: cache invalidation and naming things.” Our trouble with naming things can be blamed on the mismatches we encounter between context and knowledge. In real-world cases, this is made even more difficult because we’re rarely attempting to describe something that maps to a real-world object, but attempting to name abstract concepts that simply exist to organise code.

When we start to provide context to the users of our code by providing more descriptive comments, as well as variable and method names, our code can start to seem verbose. Certainly we want to use some discretion here (and we’re admittedly edging into the territory of coding style), but we should keep in mind that in many production environments, comments are stripped out and our code itself is minified or otherwise abbreviated. Code that goes into production is made for computers to read, and the code that we write by hand is for our fellow developers to use, reuse, extend and maintain.

The usability, reusability, extensibility and maintainability of our code are key points when establishing software best practices, and they all hinge on our ability to convey our intent through code. Although they are rarely presented in this light, best practices are generally rooted in empathy. Prior to thinking on this topic, best practices, to me, were simply ways to enhance the development speed of a project.

HOW?


We have many ways of measuring development speed, but we don’t have any good measures for the quality or level of empathy of the code that we produce – it’s subjective and relative to the consumer of the code. However, best practices can enhance the speed of development because they make the code empathetic. Our fellow developers will be able to dive into our code, quickly discover its intent, and feel reasonably confident about what it’s used for, and how to reuse, extend and maintain it. Features can be added faster, regressions can be avoided, and bugs can be squashed quicker.

In the real world, our teams will never have members who don’t have any overlaps in context or knowledge with other members. Similarly, there will never be two people with exactly the same knowledge. Overlaps will change as teammates grow, or the problem itself evolves. As long as humans are the ones developing software, we will need developers with wide differences in knowledge to bridge their gaps in context with empathy and develop solutions to some of our biggest problems.

As an industry, we’ve defined titled roles for those who innovate and develop interfaces and empathetic experiences for our end users. However, until those roles are defined for software development, it’s on us to foster empathy for one another in the code we share on our screens. Because, after all, user interfaces aren’t the only interfaces that should be frictionless, and our end users aren’t the only people affected by our code that deserve our empathy.

As developers, interfaces rule everything around, and we’re people too.