There are all sorts of decisions to be made on a software project, but some of them are "irreversible" once made. A major cause of complexity is when there are many parts to a project which cannot be changed or are too costly to change. Common irreversible decisions often include those around: The programming language, the database, 3rd party packages, public models, exposed schemas, and the communication method between services.

If the cost to reverse something is similar to the cost of rewritting it, then it may as well be considered irreversible. for example if the design makes it so difficult to add unit tests, it may as well be considered irreversible because although it may be possible to add unit tests, it will require such heavy refactoring it would been eaiser to rewrite everything, therefore that original design is irreversable. Unit tests as well as many other future issues(which you do not know of yet), can usually be solved by following standard design patterns and principles.

At the start of a project the first irreversible decision which is made is not complex in itself, but as the project goes on, then more and more irreversible decisions are made. When too many irreversible decisions have been made, the project reaches a point where the developers have coded themselves into a corner, and are forced to do workarounds/"hacks". These workarounds usually add extra complexity to the project.

It scares me when I hear: “This will never change”. Building a system while making assumptions that certain parts will never change, is the first step to complexity. This mindset leads to building inflexible systems. You should rather just assume change will happen. When someone says “This will never change” it is usually followed up with "lets build our own framework", which scares me even more because now you have just added another irreversible decision (and you to maintain that framework).

Put time and effort into designing your system to be flexible. Assume change will happen and design a system which can easily change. Your app does not have to be perfect upfront for the current or foreseeable requirements, if it is flexible enough to easily change later.

"If you're good at course correcting, being wrong may be less costly than you think."

-Jeff Bezos

The founder of Amazon, Jeff Bezos categorizes his decisions based on whether they are reversible or irreversible decision

  • Move fast and take action on reversible decisions
  • Take time and plan around irreversible decisions.

1. Move fast and take action on reversible decisions: If a decision can easily be reversed then take advantage of the low cost of change, in order to gain the benefit of having an early implementation which can be tested. The sooner a product is running in the market the sooner you can adapt, by fixing it or improving it. It is ok to be wrong when making these types of decisions, therefore make them quick even if you have incomplete information.

2. Take time and plan around irreversible decisions: Defer irreversible decisions to a responsible moment. Since there is a high cost of change once this decision is made, it is better to make the decision when you know more. Therefore the longer you can delay this decision the better, because the more that has been developed, the more you know to make a better decision. eg Dependency inversion principle will decouple the db from the business logic so that you can start writing the business logic and decide on the db later.

From Jeff Bezos's shareholder letter:

One common pitfall for large organizations – one that hurts speed and inventiveness – is “one-size-fits-all” decision making. Some decisions are consequential and irreversible or nearly irreversible – one-way doors – and these decisions must be made methodically, carefully, slowly, with great deliberation and consultation. If you walk through and don’t like what you see on the other side, you can’t get back to where you were before. We can call these Type 1 decisions. But most decisions aren’t like that – they are changeable, reversible – they’re two-way doors. If you’ve made a suboptimal Type 2 decision, you don’t have to live with the consequences for that long. You can reopen the door and go back through. Type 2 decisions can and should be made quickly by high judgment individuals or small groups. As organizations get larger, there seems to be a tendency to use the heavy-weight Type 1 decision-making process on most decisions, including many Type 2 decisions. The end result of this is slowness, unthoughtful risk aversion, failure to experiment sufficiently, and consequently diminished invention.
...
The opposite situation is less interesting and there is undoubtedly some survivorship bias. Any companies that habitually use the light-weight Type 2 decision-making process to make Type 1 decisions go extinct before they get large.

Check out these links for more info:

My design and architecture repo