There are all sorts of decisions to be made on a software project, but some of them are "irreversible" once made. While business people have to make decisions so does the tech department. Many decisions might be made the HOD or architects but every line of code that devs write are decisions as well. 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. But irreversible decisions can also lie with domain solutions and tech solutions when building new features.

If the cost to reverse something is similar to the cost of rewritting it, then it may as well be considered irreversible. for example I would call code irreversable if the design makes it so difficult to change a feature that it would been eaiser to rewrite it.

A devs responsibility on decisions being made

It is easy to blame the business for constant requirement changes because they did not do "proper analysis" before giving it to devs. But there is a degree of responsbility that developers have to take as professionals which know how to write software.

Imagine you hire a construction company to build you a house and then you ask that they build it out of mud and sticks. As professionals they won't do it, they will advise you correctly because it is their field of expertise, not yours. Software developers need to behave the same way. Of course this degree of responsiblity comes with experience, professionalism, seniority and maturity. You can not expect this type of responsiblity from a junior dev. If a team is made up of only juniors and if managers take on this responsbility the lack of an expertese will hurt them long term(don't work for companies like this).

A devs responsbilities around business requirements:

  1. It is our jobs to understand requirements and guide the business accordingly. This requires close collaboration between business and developers.
  2. Even if business says "this feature will never change", they do not dictate how the code is written, its our job to build software that does not map that irreversible decision into the code.

Often devs absolve themselves of these responsiblities, which often leads to code complexity. All too often I see devs take a reversible business decision and turn it into near "irreversible" decisions in software. They do this be they think that requirements from business are final, and assume that once written the code is "DONE". When a feature change should take a week and leads to a 6 month project due to technical difficulties, this is more often than not due to devs making poor "irreversible" decisions. It is also important to note here that the decisions made in the past, may or may not have been the devs fault depending on the information at the time.

Why irreversible decisions create complexity

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 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 even more 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 paving the road to complexity. All those systems that we hate because its so hard to change is probably due to the devs at the time thinking “This will never change”. This mindset leads to building inflexible systems. You should rather just assume change will happen. Another scarey phrase is: “Let's build our own framework", because now you have just added another irreversible decision, and more for you to maintain.

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 decisions. I apply the same thinking around tech, design and code.

  • 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