6 mins
You have 0 further articles remaining this month. Join LeadDev.com for free to read unlimited articles.

What's the best database? Or the best programming language? Fun though it might be to argue about it, there's no right answer.

It depends on the situation. If I describe the technology stack I chose for a project, but tell you nothing else about the project, you can't know whether I made good choices. We can't evaluate decisions without context.

Whether on the technical track or the management track, we're often called upon to make decisions. And of course, we prefer to make good decisions, but a lot of the time, there isn't a clear, standout, best path. The system that's most robust may be way too costly. The architecture that makes future projects easier might delay the ones that are underway now. Turning off an infrastructure component that's causing one team operational hell might only be possible if every single other team spends time learning new workflows. It's rare that any decision is perfect in every way. 

How do we get everyone to agree?

Any major technical change is likely to have a lot of stakeholders: teams who are customers of the change, teams who will need to integrate with a new system, anyone who will have extra work to do. Even people who aren't directly involved may have opinions about how the change affects your organization's architecture or engineering standards. While it's possible to have one person ram through a decision using only the force of their belief in it, we have a greater chance of success (and a more harmonious work environment) if those stakeholders support and endorse our plans. So when we send designs or plans to them for review, it can be tempting to only talk about the positives, to downplay the disadvantages. If colleagues don't know about the problems, they won't object to them, right?

This isn't the shortcut that it might seem. 

Argue the goals and tradeoffs first

When we send documentation for review, we're not (just) looking for colleagues to catch our mistakes or tell us that they like our plan. We're trying to be sure our assumptions match everyone else's. That includes assumptions about why we're doing what we're doing, and what we think the acceptable tradeoffs are.

Say we're accepting a heavier operational load for the sake of a more scalable solution, or spending extra money for features to support a particular integration. We should be clear that the scale and the features come at a cost, so stakeholders will tell us if they're not worth it. Or say we've decided that we're ok with a solution that won't support a particular low-priority use case. Unless we call that out, we might not find out in time that a major business goal next quarter depends on that feature. 

If the reviewers have a different set of priorities or know something about the tradeoffs that we don't, it's more useful to argue about those points first, before getting into the rest of the design. That means that it's good to call out this kind of high-level context early in a document, rather than burying it in the text. We can get into the details once we're all roughly aligned on whether this thing is worth doing at all.

One of the best design reviews I've attended opened with ‘Here are the reasons I don't like my own plan and why you should be wary of it.’ The RFC (Request For Comments) author was honest and laid out the risks that he was proposing to take and the challenges he expected to encounter. Then he explained why he thought the project was still worthwhile. By spelling out how he weighed the advantages and disadvantages of the plan, he let reviewers decide at the start whether they agreed with his assessment. (They did.) Then the details followed. By giving the reviewers all of the information up front, my colleague helped the reviewers reason about the plan. They could trust that he'd thought through the design and that he wasn't hiding anything. 

It's a team sport

If we don't give reviewers all of the context they need, we're wasting their time and our own. Withholding information can lead to wasted work and project delays. Stakeholders may think they're aligned but discover too late that a problem they thought was solved is still on the table for them.

When we're clear about the disadvantages of our plans, we also encourage our reviewers to help mitigate those disadvantages. This might mean that someone else suggests an iteratively better idea (or a completely different one) that will still achieve the good outcomes but avoid some of the bad ones. It's not always easy to be receptive to better ideas. When you spend a lot of time thinking about something, it becomes harder to be objective about it, and it's easy to fall in love with our own solutions rather than with the problem we originally set out to solve. So, it's essential to be honest about discussing goals, tradeoffs, and roads not taken as early as possible, before our familiarity with an idea makes it hard to accept alternatives. 

Reviewers shouldn't feel like opponents: they should feel like they're on the same team. Even if different teams may have different immediate goals, everyone is working together to solve the same problems. 

‘What were they thinking?’

If you've ever encountered a system with design decisions that seemed completely off the wall, you may have wondered why those boneheaded past people could have chosen the path they did. No matter how good your own decisions feel now, expect that someone (maybe your future self!) will look back and wonder the same about you. 

The decision you're making now may not always remain the right one. The scale will change, the tradeoffs will be in a different balance, or a new technology will be worth the cost of an upgrade. As future people think about that decision, they'll want to know the context in which you made this one. 

RFCs and Lightweight Architectural Decision Records are good tools to summarize decisions and spell out the tradeoffs that were considered. I like to go a step further and encourage anyone who really dislikes a plan to write a dissent – Supreme Court style. The dissent is not intended to change anyone's mind: all of the information and arguments it contains were available when the decision was made. But it records more context about the decision, and respects that there may not have been a simple best solution.

By writing down the disadvantages you know about, you can tell judgy future people that you knew what you were doing: you made a deliberate decision based on the constraints and information you had at the time. As a bonus, if the constraints change, the future people will know it's ok to change course.

In conclusion

Few decisions are straightforward, perfect wins in all categories. As we become more experienced, we realize that most engineering choices boil down to ‘it depends’. In fact, sometimes all of the paths are bad and our mission is to make the least bad decision. 

The presence of disadvantages doesn't mean we have to avoid a certain path. They mean that we've made a deliberate decision to prioritize one set of pros and cons over another, and that we knowingly accept the downsides of our decision.

When we ac-cent-uate the negative, we let our colleagues review our work and suggest workarounds, we find out early if any of the disadvantages are actually fatal, we build trust, we open the door to better alternatives, and we provide context for future-people who will wonder why the heck we did what we did.