Refactoring to maintainability

Context is everything

The setup

A couple of weeks ago I wrote a post in which I uttered the sentence context is everything. So I wanted to expand a bit on that idea here. In part, the reason I wanted to write this is because it took me a while to understand it: I used to complain about certain decisions done in the past, without knowledge of the context in which those decisions were taken.

Past context

A decision, any decision, is taken around a context. Maybe it was a bad decision at the time, maybe it was good. But is all based on the information and goals at the time, both those that are publicly known and those which are not.

When trying to evaluate a decision taken previously, it is important to understand the context, because it will be (most probably) a different context to what is available at the current time. And contexts are big: They include the people available, technology, situation of the company, situation of the product(s), expected benefits and cons (both for the company and for the individuals taking the decision), what is the situation of the market (both locally and, nowadays, internationally), the state of internal politics, and a few others.

Record it

There is so much information, and so much of it gets lost with time. If you don’t remember why a decision was taken, it will be difficult to evaluate that decision in the future.

I was introduced by the awesome Bob Gregory to the concept of Architectural Decision Records(ADRs), which serve as a way to record all the decisions taken (so it is easy to know which decisions have been taken), and to keep (as much as you can) the context, the publicly available one, as sometimes there is secret context that people don’t want to divulge (sometimes it is easy to see when there is some secret context because the decision is contemporarily bad based on the public context).

You should use the same technique not only for architectural decisions, but for any other kind of decision taken. I believe that DRs, as a general concept, is a good practice.

When the context change

So far, I have been talking about understanding the context in which decisions were taken. That doesn’t mean that a no point you should not question keeping those decisions.

With time, context changes, all the parts that I mentioned in the second section plus the knowledge of the effects of decisions taken. And when that happens you need to reevaluate those decisions, and sometimes reverse them. Not doing so is reckless and a sign of bad leadership.

Looking at the DRs from the previous section, I will say that you want to revisit a decision a year and five years in the future, as time gives new perspective and knowledge (let’s drop a reference to the magnificent Rouletabillie), and you can evaluate if a different decision could have been made. Learning is important, never stop learning.

Balancing present and future

When talking about context you need to also look at the future context. How the context could change and evolve is an important part of taking decisions that have better chances to stand the test of time.

But that doesn’t matter if the in the short term the decision is actually harmful to the product, the company, the stakeholders … You need to balance present and future needs.

If you skim on quality because you think you need to go fast, fast, fast now, you are seriously hampering your ability to improve, change and even pivot, in the future. There is a case that skimming on quality will start to hurt you nearly immediately.

But if you are looking only at the future, you are making also your current situation worse. There is no point on thinking that microservices will be useful when you have millions of users, if you can’t deliver a product useful for thousands of users: microservices do add a lot of complexity.

Somehow, some companies manage to choose badly on both cases.

The context clash

Whenever you have two (or more) people wanting to have opposing decisions taken, the first thing is to understand the context on which they operate. Goals are part of that context, and nearly always the goals are in clash. Sometimes there is knowledge on one side that are not present on the other side. Align knowledge and goals, and the chances of taking a common decision are greatly improved.

Example: The DB mammolith

I worked once at a company in which there was a massive amount of business logic in the DB. Consequences of that is that it was difficult to change it safely (there were tests around it, but they took a few hours), and that the process that the business logic covered was extremely slow (taking around 15 minutes something that should be just some seconds at most).

But part of the context (as my understanding goes) is that, when the DB developer created it, the company was having massive issues with performance and deadlocks, and the DB dev was able to sort them out quickly. That solved the issues.

Would have I taken the same decision based on the context at the time? Would you, if that have meant the company will start actually earning money and not cause issues to the clients?

Example: The architecture decision

A completely different example is a company that used a microservices architecture (event driven) from the get go. By default, I am not a big fan of your first version (even second) of an app/product to be based on microservices. But here comes the context: it was a startup that started with a lot of money, and they just went ahead a got a big number of personnel from a consultancy. This allowed them to quickly iterate and move forward without teams getting in the way of each other. The consequence was a pretty well featured web app developed and put live in less than a year; not a proof of concept, not a beta version, but an actual useful website.

The outro

So there are three ideas that I want to leave you with:

  • Understand the context to understand decisions taken
  • Record decisions and their context
  • Reevaluate all decisions when the context changes