In a previous blog post, I discussed the philosophy of Human-Centered Design (HCD) and its usefulness to software engineers in their everyday work. In that post, the HCD philosophy is defined as an:

an “approach to systems design and development that aims to make interactive systems more usable by focusing on the use of the system and applying human factors/ergonomics and usability knowledge and techniques.” In essence, HCD is about designing our products and systems around users and stakeholders, their abilities, their mental models, and their environments.

Without rehashing the whole post, it argues that software engineers make design decisions that impact stakeholders and that a human-centered mindset is an excellent tool to help engineers make those decisions. While I offered some basic suggestions to help engineers take the first step in an HCD journey, I did not expand very much on the practice of HCD as opposed to the theory; this post aims to dive deeper into the former.

The first thing that needs to be said is that HCD is a philosophy, often used by professional UX designers who often have a wealth of professional and educational experience doing design work. Reading this post is not going to turn a software engineer into a professional UX designer, and it would be doing a disservice to designers to believe you could condense their knowledge and expertise into a blog post. Good design is not simple. What I want software engineers to take from this post are some strategies they can focus on to help their design decision-making process. This is useful because even if ‘designer’ isn’t in our title, software engineers are often in a position where human-centered design methodologies can be applied. Sometimes our team doesn’t have dedicated designers. Sometimes designers are focused on the UX of the end user, and not how other team members might be consuming our own work or microservices. Sometimes we might be building an internal productivity tool. There are many situations where we may find ourselves momentarily wearing the hat of a designer.

Consider a hypothetical software engineer that wants to try and solve a mail room inefficiency at the institution they work for. How do they accomplish this task? Broadly, the work is going to fall into four categories:

  1. Discovery
  2. User Research
  3. Design & Prototyping
  4. Implementation


Discovery is about understanding the problem space. Knowing the mailroom is inefficient is not the same thing as understanding the mailroom and the root cause of inefficiencies. Even if you already have some idea of a target area, you need to elaborate further to understand the problem.

A frequent and large mistake software engineers make is solutioning during discovery. For example, say someone saw mailroom staff taking a long time to generate address labels because it was a multi-step process. They might tell you to write up a macro that generates the label. This is creating a solution to an ill-understood problem. If discovery is approached with the idea that the final output of the project must be a macro, it will severely hamper future design efforts. A macro might be the best tool for the job, but it might not be. I’d caution you from setting out on a project with a plan to “build an app” before you’ve fully understood the problem space. With this mindset, it’s easy to fall into a trap of searching for problems that fit a solution (an app) instead of understanding the problem and then deciding on the best solution.

The most powerful tool during discovery is the stakeholder interview. Your goal is to try and tease out the actual problems from people, whether they are aware of them or not. During interviews you want to steer people away from solutioning, don’t ask how you can fix a problem, seek to understand the process. Ask a user to walk you through their day, ask them about the tools they use, and the methods they use. This will often surface pain points and problems. Next, dive deep into the why of these problems. If the mailroom is slow, why? If address labels take ten minutes to print, why? If you can’t directly copy an address from the database, why? A problem that looks like one thing will often actually be another once you drill down into the why. Conduct multiple interviews with different types of relevant stakeholders. You want to interview the mailroom staff, but also the mailroom management.

Once all the interviews are done, you want to analyze and synthesize the information you’ve gathered. The output of discovery should be a problem statement and a very clear set of requirements and constraints that a solution to the problem needs to satisfy. In this case, your problem statement could be that mailroom staff are unable to work efficiently because the address label printing process takes ten minutes per label. A requirement to solve this problem could be that you need to decrease the average label printing time to five minutes. A constraint could be that the solution should operate without incurring additional costs. These examples are both business related, but there can also be technical requirements and constraints. If the mailroom uses an oracle database, that’s a technical constraint your solution must work within.

A fully-fledged discovery effort can take a full team of designers and analysts weeks, depending on the scope of the project. There are other tools and methods of analysis that a team will often use as well. How much effort you should dedicate to discovery is contextual. If you just have a ticket you’re looking to understand better, maybe just have a few discussions with co-workers. If you’re trying to design an entire large application from the ground up, discovery should probably take at least a full sprint, probably more (and should probably include design experts and analysts). For the mailroom example, It’d be reasonable to spend half a day of interviews and then half a day of analysis to produce a requirements and constraints document.

To condense a lot of words into a few key points, the most important aspects of this small-scale discovery are:

  1. Avoid solutioning in this phase. Seek only to understand and define the problem 
  2. Conduct stakeholder interviews with those who are impacted by the problem 
  3. Synthesize those interviews into a coherent problem statement, with requirements and constraints.

User Research

User research is a crucial step in the HCD process. It’s how designers try and understand what their users need, what they want, what they’ll use, how a solution can help, etc. Professional user researchers will use a variety of data collection and synthesis methods. They will conduct different types of interviews, run activities with users, and have resources at their disposal to help find and make contact with users.

In contrast, as software engineers you may not have the same resources available to you that a user researcher would, but you can still gather valuable insights with a few user interviews. A few 15-30 minute conversations can drastically impact how you approach a problem. Here are some examples of key things you want to better try and understand from your interviews.

  • Who are the users?
  • When, where, why, and how do they currently accomplish the task? 
  • What do users perceive are problems with their current practices?
  • User’s wish list for improving how they currently accomplish their task?

As with stakeholder interviews, you often want to ask follow-up questions to better understand the reasons for the user’s answers. This lets you dig deeper into root causes. If a user tells you they don’t like using a particular piece of software or tool, you want to explore why. Are there too many clicks required to do common and simple operations? Is it unintuitive and complicated to use? If the software is unintuitive, how come? Do the data models not map conceptually well onto the problem?

I’d caution you from setting out on a project with a plan to “build an app” before you’ve fully understood the problem space. With this mindset, it’s easy to fall into a trap of searching for problems that fit a solution (an app) instead of understanding the problem and then deciding on the best solution.

It is often particularly useful to observe users doing their day-to-day work in the problem space. If you’re designing a mailroom tool, spend a day in the mailroom watching people work. Get one of them to teach you how to go through the current workflow for the problem you’re working on. Take particular note if the user’s actions ever contradict what you learned during interviews, or if you notice something that wasn’t mentioned in the interview but seems relevant. Usually, there is some root cause or reason for the dissonance between what a user thinks is important for you to know, and the actual user’s actions.

The end goal of your user research can be proto-personas. Just write a paragraph or two on the different types of users that could be using your solution. Focus on the varying needs and problems each user faces. Depending on the scope of your work, this step might not even be necessary. Just your notes or the knowledge gained might be enough to help steer your design decisions in the correct direction.

This kind of limited user research can be defined as “ad-hoc” user research. Your goal is to understand your users through interviews. Shadowing can also be a very powerful tool to watch users as they use existing solutions and workflows. Once you’ve conducted this research, a great way to synthesize your knowledge gained is with the creation of proto-personas.

Design, Prototyping, and Implementation

Only after you’ve gained a deeper understanding of the problem space and your user needs can you begin designing a solution that fits the requirements and constraints outlined in discovery. This generally starts with high-level ideas that get refined with technical details and prototypes. Then once the design is more or less finalized, the technical details are fully ironed out and engineers take it across the finish line with implementation.

I don’t want to dive into design methods because there are many and this is a task many software engineers routinely engage in already. What I want to stress is that including HCD in your design and implementation is both simple and difficult. Once you have the knowledge gained from discovery and user research, that knowledge should guide every decision you make. It should always be at the back of your mind whenever you’re faced with a choice. Always put yourself in your users shoes, and always refer back to your requirements and constraints. You don’t need to disregard other forms of analysis and design, but make sure you’re always at least thinking about how a decision is going to affect a user. This kind of design awareness coupled with the knowledge gained in the previous two steps can have a huge impact on the quality of a design’s user experience.

Using HCD in your Day to Day

It’s not practical nor is it necessary to engage in HCD for every ticket that comes across your desk. Often product owners and designers have already given you a clear set of requirements, or maybe it’s just a simple bug fix discovered during verification. However, it can be beneficial to orient yourself towards HCD any time you find you need to wear a designer hat. For some software engineers, that will be more often than others. It will depend on your industry, your company, your team structure, your company culture, etc.

If you’re fortunate to work at a company with product managers and UX designers, you may rely on these teammates to conduct discovery and user research to identify problems to solve. If this is the case, ask to view the research or ask to be included in some of the research exercises so you can hear it firsthand.

My work often consists of creating or updating microservices on a distributed platform that are going to be consumed by other microservices being built by other engineers. When I’m working on a ticket like that, I often do a mini version of the 4 stages I outlined above. I take an hour or two to chat with relevant stakeholders and understand what problem the ticket is trying to solve. Then I go and chat with the current or future consumers of the API to understand exactly what they are looking for and why. This knowledge then guides my implementation and design of the solution in the ticket.

Every once in a while this kind of awareness really pays off. I might learn that what the ticket is asking for, isn’t actually going to be helpful. Being upfront about understanding the big picture and design behind tickets has saved my team many hours of refactor work and bug fixes that would have been required had I just jumped right into the ticket.

Conclusion and Other Resources

Every software engineer could benefit from thinking about and implementing a little HCD in their day-to-day work. You don’t need to be a designer to take some small steps that let users guide your design decisions into better products. The two most important takeaways that I hope you’ll remember are:

  1. Never solution without understanding the problem first
  2. Always keep the user’s needs in mind as you make design decisions.

If you are more interested in potentially making a jump into design as a career, or you are more interested in more methodologies and resources, two excellent books I can recommend are The User Experience Team of One by Leah Buley and Universal Methods of Design by Bella Martin and Bruce Hanington.

If you are passionate about building or designing quality software with good user experience, Nuvalence is hiring!

Interested in learning about the philosophy of Human-Centered Design (HCD) and its everyday usefulness to software engineers?