You know what they say ...
Time flies when you’re having fun.
The early bird gets the worm.
The sooner the better.
We have a medley of phrases and idioms that suggest time is of the essence, and it’s a concept that holds true even for software engineers, especially when it comes to balancing the right amount of time — not too much, not too little — in the design and build phases of a solution. For many engineers, the timing of decisions and the frequency of feedback is everything.
Meredith Haynes, a staff engineer at Grubhub, takes an iterative approach. When designing features for the food ordering and delivery platform, Haynes prioritizes building the solution’s core framework, then molds its features in iterations based on feedback from user experiences. “Shipping a minimal solution early and learning as much as we can about users’ needs from their interaction with it has always produced the best results for me,” she said.
At Flexport, a supply chain management platform, Staff Software Engineer Patrick Auld breaks his design-build process down into two areas of development: designing a solution and applying feedback. Once Auld hits the 80 percent mark of a completed design, he shifts his attention to building. To reach the remaining 20 percent standing between him and the completion of an application or feature, he finds that feedback loops are a must.
“Even early on, a sacrificial architecture or mocked-up user experience can teach you something important,” said Auld. “Put something in front of users, and get feedback as early and often as possible.”
For both a design’s framework and a user’s insights, early is best for these two engineers. Built In Chicago sat down with Auld and Haynes to learn more about their design-build process and what their methods actually look like in practice.
When tasked with designing and developing a solution, do you have any hard-and-fast rules that dictate when to stop designing and begin iterating?
I’ve learned to recognize the point at which I’ve stopped designing for the immediate needs of the application I’m working on and started to design for potential requirements. It’s at that point that I know to pull back and ask myself, “Is this work we know will be helpful to the user, or are we starting to design for eventuality?”
Throughout most of my career, I’ve used some form of the agile software development methodology, which has taught me that an iterative approach to product development is key to delivering a useful solution. I’ve seen many development hours spent on features that might be quite sexy, but provide users with little of what they need. Shipping a minimal solution early and learning as much as we can about users’ needs from their interaction with it has always produced the best results for me. I am comfortable with concluding the initial design of an application when I feel our team has arrived at something that supports the minimum viable product requirements but is also open for extensibility. If we’ve put together the blueprint for an application that allows for change without rewriting the core framework, then I know we are ready to start building.
If we’ve put together the blueprint for an application that allows for change without rewriting the core framework, then I know we are ready to start building.”
Give us an example of your design-build process in action on a recent project. What were you tasked with creating?
My team recently created a web-based series of help menus in React that is accessible to drivers from our mobile applications while they are fulfilling orders. The main benefits of a web-based help menu are a shorter time-to-market and a single codebase, rather than building the feature in multiple mobile platforms.
We started by reducing the diagrams that our visual design team created into the views we would need to build, which included a list of options and a landing page. These views can contain different content depending on the user’s selection, but the layout is always the same. We broke each view into its necessary elements, then used a content management system to configure the content. Each help menu eventually results in a landing page with several possible calls to action.
We knew the list of things that the application would allow the user to do with these CTAs would change, but the application would always need some framework for communicating back both to the mobile apps and our application programming interfaces. Designing that framework was what set us up for success and now allows us to quickly implement new views and actions when we determine what the users need help with most urgently.
When did you know it was time to stop designing and start building?
Once we had arrived at a design that accounted for all of the basic requirements of the application — for example, navigating a list of options and choosing an action — we not only had something we could begin to build, but we knew that it would support future enhancements. The most important piece of our design was the schema that messages sent between our application and the mobile applications would need to adhere to. We had to create something that would allow for communicating the relevant information, but wasn’t so opinionated as to only accommodate certain scenarios.
When tasked with designing and developing a solution, do you have any hard-and-fast rules that dictate when to stop designing and begin building?
If you know more than 80 percent of what needs to be done, then it’s time to build and validate that. You have to build in order to test your assumptions throughout a project; there is no other way to get feedback. The last 20 percent is the hardest part, so you want to have a feedback loop to discover it.
Done right, this means you are building early on to test high-level decisions. From there, you design more based on what you learn and build out to test those ideas. Design and build happen on a loop throughout the project with an inverse relationship. It’s primarily designing with some test builds to start, then as you learn more, the workload inverts and settles on you spending most of your time building.
You have to build in order to test your assumptions throughout a project; there is no other way to get feedback.”
Give us an example of your design-build process in action on a recent project. What were you tasked with creating?
Our team recently built a tool to validate data of inconsistent quality across multiple sources and raise exceptions where inconsistencies were found. We did an initial design, then pivoted to making a spike we knew we would throw out. It was a dirty hack that mostly worked, and we could show it to end users. We completely changed our design based on the findings.
There was significant work up-front to set expectations that the pilot was a throwaway, and we would have to turn it off to avoid maintenance costs. Still, we got pushback and feature requests from teams. We leveraged the feedback to show the value of what we were building to other stakeholders, and we ended up maintaining a minor part of the pilot that we knew we would be recreating as it was so helpful to people.
Without the pilot and user feedback, we would have built the wrong thing. It wasn’t far off to start, but it would have taken rework to get the features people ultimately ended up needing. With a 2- to 3-week spike, we validated our idea was sound, found a specific problem we could solve for users and felt motivated as a team to know that this was important work.
When do you know it is time to stop designing and start building?
You should likely already be building.
Even early on, a sacrificial architecture or mocked-up user experience can teach you something important. Put something in front of users, and get feedback as early and often as possible.
The most challenging part of building and designing iteratively is setting expectations with users and other stakeholders. Everything you create has to be done to test an assumption or idea, and those tests can fail — when that happens, you must throw away or back out on that change. The smaller the iteration cycles, the less risk there is to this, both in terms of lost effort and user experience flip-flopping significantly.
Find decisions that are one-way doors and commit to them, then start iterating. Reversible decisions are precisely that: reversible. Test them out and deliver some good along the way.