A large payment company needs to replace the heart of their production system, the code through which all payments travel. A friend described repeated failed attempts replace it, now the 3rd attempt in a decade. Once again the programmers were building a “better” version of the code—better language, better programmers (just ask ‘em!), better practices. The plan? Build it better then switch it on.
Third attempt. Smart, accomplished people. Doing the same dubious (to me) thing for the 3rd time. And as soon as I heard the plan I thought, “That doesn’t make sense to me.” The bigger & more critical the system, the tinier steps I want to take.
I’m not at all saying I’m a better software designer than these folks. They know more details about the current system. They have more context about the business. They know their technology stacks. Their organizations. And I may be wrong—their way forward may be better than mine. But we definitely disagree.
Empirical Software Design teaches intuitions about:
What makes for an effective point in the space of all possible designs. (There are generally a few good ones & a bunch of bad ones.)
Navigating from the current point in the space in a desirable direction, what I call the Succession Problem.
Not Rationality
Some styles of design purport to proceed rationally. Take the requirements. Turn a crank. Out comes The Design. I’ve seldom seen this ever even seem to work. Too much uncertainty. Too many changes.
Uncertainty about features. Remember that software design is preparation for change. Any design will make some features easier to implement & other features harder to implement. But which features?
Uncertainty about business. How fast will you grow? When will funding appear? Which new markets will you need to cater to (leading to uncertainty about features)?
Uncertainty about technology. What technology will we use in the future? When will it be introduced? How will it spread?
Uncertainty about team. Who will be on the team? What background will they have? How big will the team be?
And as soon as the software goes into production, any certainty on any of these dimensions evaporates.
If you don’t have answers to these questions, then you can’t have a rational process for design. You are going to have to rely on human intuition.
Precis
Here are few of the ways the Empirical Software Design intuition commonly stands out:
Safety of evolution is more valuable than efficiency of implementation. The wonders of a future design & how fast you can build it in isolation don’t matter if you can’t get there from here. The larger the system, the more important safety becomes. Smaller, safer steps.
Spending later is valuable. Today is the least experienced & least informed I will ever be. Don’t make any decision today that I can responsibly put off until tomorrow.
Earning sooner (& getting other forms of feedback sooner) is more valuable than keeping projects simple. If we assume we are going to make mistakes & learn, then we should go into production today (but safely). Software designers often seem terrified that as soon as the system is in production they will never be able to make another design change ever again.
Coupling, as revealed by actual development, drives cost. Some coupling is obvious but some will only be revealed over time. Be prepared to notice.
Increasing cohesion often reveals the potential for decoupling. Spend some time just increasing cohesion.
Put these biases together & you’re going to have a different path to your new design than is frequently practiced.
an incremental development/deploy based on many small_steps/tiny_bangs might avoid a 4th attempt
I find it so hard to strike a good balance between coupling and cohesion. I never know when my design requirements can change and it can make so much implode in an instant.