Continuous Refactoring

Software is very interesting, it's amazing how little things make a huge difference, being able to see all the small intricacies and how the pieces fit together is a complex and fascinating task. The more we understand, the more we learn effectively, better we can do it. Software complexity does not reduce, it only grows, working with a relentless mindset of continuous improvement is the only way to go forward. Refactoring is often seen as a "bad word" a big spooky thing because everybody believes is busy, so why are you risking breaking a lot of things if you can move forward and "live" with the problems. XP (Extreme Programming) got this right from the get-go, you need the principles and values. XP has a value called: courage; courage to do refactoring, especially when the conditions are not in your favor, considering monoliths and distributed monoliths the odds are never in your favor. Once you start doing so, slowly put all guardrails in place, would such conditions still be against you and your team? Problems can be temporary or forever it all depends on how we perceive them and what we do about them. As soon as we change our mindsets, faster we can reduce the problems. 

Human Nature

More than 20 years ago when I started in the industry, I remember my first teacher talking about mindset. He was telling me a fable about Pigs. The tale was about a tribe of people who like to enjoy pork bbq, however, they have a rather peculiar method of doing the bbq.

What they did was literally burn the whole forest, after the fire was done, they would go to the forest and look for pigs, some might be a bit well-done, beyond the point, some might be too raw, and eventually, some would be ideal. Such process was always how they rolled, however, things were getting harder and harder since Forrest was not infinite and they had to travel far and far to find a new forest to throw fire. Eventually, a guy invented a bbq grilled with fire on the ground, this was a breakthrough innovation because now they were not required to burn the whole forest anymore. However, people did not like it and did not follow and still wanted to continue to burn the forest. 

Human nature has the tendency to get used to how things are, good or bad. The human being gets used and to break such cycles and addictions is difficult but is possible. Sometimes because they don't know any better, other times just because that was "the standard". However, humans can change and learn but is a process, it's a long-term commitment, that takes time, energy, patience, and love. 

Driving fear out

One thing that leadership needs to do is to Drive fear out. Engineers have a fear of touching somebody else code because they want to succeed and do not like to fail meaning they do not want to upset their managers. Management often sees refactoring as a risk and something that should be avoided because might affect deadlines. What engineers want the most is to do refactoring, it's to change software and make it better. However we won't do anything if we have fear, that's why we need to drive this fear out and create an environment where the culture of change can flourish.

Such culture can be created by simple but yet courage acts like:

  • Do some refactoring as part of the current PR
  • Create a refactoring story and negotiate to add to your current sprint
  • Ask for some refactoring as part of the code review process
  • Give time for engineers to make improvements, even if is just 1 day per sprint
  • Push back when the complexity is too high 
  • Talk about such improvements in retrospective

IMHO the best thing is to always do something every day, even if is a small refactoring. Keep in mind, that we cannot start with the refactoring, we need to start addressing the fear. Then we can do refactoring.

Netflix has this interesting concept: "Do not please your manager". We need to do what is best for the customers and for the company, seasoned engineers will push back management when does not make sense. However at the same time, engineers do not own the truth, they can be wrong as well, or they might want to refactor something that will be decommissioned or bring zero return for the company, that's why conversations need to happen.

The problem with this engineering mentality is that you don't create critical thinking, you don't create curiosity and you put all responsibility for improvements on managers, and that cannot scale and will not end well. Systems are big and complex, everybody needs to be collaborating and working hard to improve them. 

Engineers are not and cannot be "Victims" they need to be adults behave like grow-ups and do their best no matter what. Managers need to support engineers and give good advice, one good advice is to do Refactoring.

Negative reinforcing loops

The problem with not doing refactoring is that little by little the system is dying and will become a legacy full of problems inefficiencies, bottlenecks, and anti-patterns and will need to be re-written eventually. Even if you start with a green field and are doing all the right things, people change, people come and go, management changes, companies change and if you stop improving you will start a decay process. All software suffers from this and that's how we create systems that suck.



Such doom downward spiral happens because often when you are not doing refactoring you are also not doing tests, not improving the coverage, not adding tesing diversity and diversification. The design tends to decay (if ever existed), libraries and frameworks get deprecated, does not take long to anti-patterns be everywhere and they will proliferate faster than the good things. Because if you don't do refactoring, you are not doing the good things.

The year was 2007, I was working in a big company in Brazil, and we were building a complex and important financial system, I remember the CEO of the company just wanted one thing "A system that lasts for years" he was already sick of re-writing everything over and over. 

You can't get everything right all the time, mistakes happen, especially at full speed, but you need to learn as you learn you need to apply this learning, and that is how we create a different reality.

Positive reinforcing loops

We need to do refactoring because we need to keep the system alive, we need to make it better, this is how we will reverse this doom-down spiral to a positive reinforcement loop. The mindset is like this:

As we learn:
  • How to be better engineers
  • How the business works
  • How to better deliver value to the customer
  • How we can make better designs
  • How we can improve efficiency 

We do add tests and do refactoring, resulting in better software, which results in a better digital product that will deliver better experiences for our users. UX is also about engineering:

  • If the site/app is down, the user cannot do anything.
  • If the site/app is slow the user will suffer
  • If the site/app is confusing and not reliable the user cant trust us
We can't deliver a better user experience just by doing beautiful UIs! We need efficient infrastructure and backend services that scale and are reliable like water. As this cycle spins, it goes faster and faster, it gets easier over time and the team confidence grows, and everything gets better. 

Throwing salt or just adding balance...

So should we refactor all the things all the time, well I definitely think we need to refactor more than we do but here are some facts and food for thought. 

Kent Beck's new book: Tidy First? Talks about tradeoffs of refactoring(Tidy).
One of the interesting ideas in the book is that a PR could have Behavior(B) changes or Structure(S) changes. Such PR could be very big, and ideally, it should be broken into several small PRs with Structure and Behavior changes split into separated PRs. I saw a similar idea before in another book called: Philosophy of Software Design. 

The term was a bit different: Strategic vs Tactical programming however the two concepts are in full alignment. In the philosophy of software design John Ousterhour calls out that if you just do Tactical programming (Features) you will end up going slow, and you need to do strategic programming(Design) which is not a feature, but design improvements that make you do faster again.


As you can see there are multiple theories converging on this idea that you really need to do refactoring. One of the cool things about Tidy First is that Kent gives some criteria for when to refactor now, later, or even never. One thing he mentions is that there is a "promise" or a "gamble" and that's the refactor dilemma, you don't know if you will make it better or worse. So how do you know you will deliver something better, I was thinking about that and a couple of things come to my mind:

  • Architecture is also a gamble, how do you know it will scale and deliver what you really think - that links us with evolutionary architecture and lean principles like reducing batch sizes, to reduce the change it goes wrong.
  • Tests (I think we should do them) but they are also a gamble, they might not payoff, in fact if they are breaking all the time, they add negative value, there is nothing worse them tests that you cannot trust.
  • Feature should be the same as Refactorings - they are also a gamble, how do we know if they will pay off or not (Discovery process) - but often we don't question why we are doing feature but we question why we are doing refactoring.

I'm a big believer in tradeoffs, analysis, and Inventories. IMHO to really decide if makes sense or not, these tools can help us figure out the cost + some code commits frequency or bugs frequency we could calculate or some good sense of the benefit around the refactorings. For distributed monoliths IMHO more analysis is required because of the blast radius, for monoliths where you can leverage the IDE more immediate action can be done.

Besides if we need to perform more analysis, tradeoffs, and inventories, refactoring needs to happen one way or another. Blast radius and Isolation are key in this sense. Analysis and Refactoring will create good momentum for your team.

Pride

Edward Deming, an 80s quality guru and big influencer of his management theories in Japan post-WWII inspired Lean Thinking and Lean manufacturing. Always said: "People just want to feel pride". Pride about their jobs, pride about the things they build. It's not that complicated, is very simple in fact. 


Refactoring is one of the best ways to boost engineers' pride at work if not the very best. 

Continuous Refactoring building a culture of excellence

I deeply believe refactoring is the way to go. I always believed that the best products I built were refactored continuously. Not naming names, the worst companies I worked, the worst projects I did were the ones where refactoring was not welcome and change was not happening. Refactoring is life! 

Inspired by the classic "Ted Lasso" Futbol is life!

Cheers,

Diego Pacheco

Popular posts from this blog

Kafka Streams with Java 15

Rust and Java Interoperability

HMAC in Java