The pull to start writing code is strong when building a new system. It feels urgent, but it isn’t the most important thing you should be doing…
When people think of software development they often think of a programmer typing 0s and 1s into a green screen all alone in a room drinking Mountain Dew. Most software isn’t written by a lone developer drinking Mountain Dew. In reality, projects often have many developers and many more requirements than a single person can maintain their brain. Projects are rarely as simple as “build me x.”
A key problem when building software is making sure everyone is headed down the same path. Building the wrong thing is often considered a requirements problem. We had the wrong requirements, therefore the wrong thing was built.
That is part of building the wrong thing, but just because we have good requirements doesn’t mean everyone knows what we are going to build. Having a design gives us a way to quickly get everyone onto the same page.
Designs also give us the ability to communicate more effectively while on a project. People can reference things by name and actually understand what those names mean.
Another way communication can be enhanced is through consistency. If everyone does things in the same way, you end up with less first-principle problems. The situation where everyone feels it necessary to recreate the world with each new problem. If everything is done the same way, you end up with people more focused on solving the business problems inside some constraints. Instead of everyone feeling the need to make each problem its own unique snowflake.
Coordinating the activities among multiple developers is not an easy task. Oftentimes, tasks have dependencies on other tasks. In those situations, it is often important to plan your project to ensure that you can hit your desired deliverables. If you don’t coordinate your work, you could end up with a situation where you have five developers, but only have work for three of them. That’s extremely inefficient.
Below is a dependency diagram for a hypothetical eCommerce system.
Below is a plan that leaves developers on the bench starting in Iteration 5.
Below is a better-designed plan.
Anytime you end up with a plan that leaves a developer on the bench, I can assure you some other developer is being pressured to complete some work faster than it should be done. The example above probably isn’t that bad since we could just pull a developer off early. But many times, these sorts of problems arise early in a project.
Speaking of bugs, a core problem with bugs is that they contribute to rework. Lots of rework basically makes it difficult to make any forward progress on a project. Sometimes rework can become over 50% of all time on a project.
Bad design is a larger source of rework than bad code. And if you get the design wrong, fixing the design once you are coding is very expensive. If you fix the design before a single line of code is written it doesn’t cost much to fix. Updating diagrams is easy. Updating a few thousand lines of code isn’t so easy.
If bad design produces more rework than code it makes sense to spend some time on it, right? Do you want to know a larger source of rework? Requirements. Requirements are the single largest source of rework.
If requirements create more rework than design, we shouldn’t spend more time there. We should find a way to identify requirement issues before writing code. This is called design.
Designing the software will help to ferret out some of those hidden assumptions and missing requirements. Doing design before writing code will help reduce the overall cost of the build.
Designing software can have another benefit. If you design to encapsulate volatility, you can help improve the maintainability of your system. A common problem with software is that a product starts off with a good velocity of development. But over time, the velocity decreases. A key reason for this reduced velocity is the system was never designed to encapsulate the inevitable changes that will occur over the lifetime of the product.
All this design seems like a crazy amount of effort, so can’t we just get in there and start writing code?
You can, but you will end up with a lot of rework and/or bugs. Spending time reworking a system can easily become the majority of what a team works on. You will likely spend more time doing rework than adding business value.
Requirements —> Design —> Build —> Test
Gary Mogyorodi, “What is Requirements-Based Testing?“