Minimal change development

Tunnel

There is a style of development out there that encourages making mostly minimal changes. Do the least amount of stuff to get your feature running.

I’ve heard this advice many times over the years.

This seems to be mostly used as a tactic when people are scared. Scared of changing the code.

It’s normal to be nervous when you work with crappy code, but keeping changes to a minimum will also keep the code crappy. It’s a vicious cycle: you keep making small changes, the code doesn’t get properly refactored, it stays crappy, you stay scared, you keep making minimal changes.

The only time for minimal changes should be when backporting bug fixes, when you issue some emergency fix or when you write a dirty hack.

While I don’t think that minimal changes are intrinsically wrong, most people get the wrong idea and try to do it all the time.

People think that the only way to add new features without introducing lots of bugs, is by making the smallest changes you can. This might be true, but at the same time you’re increasing entropy, and in the long run it will hurt you.

Think about it, you focus on a small bit of the system. It’s like you have tunnel vision so you will implement a local solution instead of a global one.

It’s like when searching for a function’s minimum, you can get stuck in a local minimum far away from the real one.

If you do implement a feature with minimal changes in mind, you need to follow up with refactoring. Not code refactoring, but architecture refactoring.

If you keep going without stopping to refactor, you may get your tasks done, but the system’s architecture will suffer because entropy will increase.

Like with everything else, there is a time and a place for making minimal changes, but it has to be used with moderation.

Architecture refactoring


Code refactoring is better than nothing at all, but I don’t think it helps too much.

After an opening line like that, I better explain what I mean.

In the context of refactoring, software teams can be split into two categories: teams that refactor code and teams that refactor architecture.

Code refactoring teams

If your team is refactoring code all the time but things seem to stay the same, you may be in a team that practices just code refactoring.

Imagine that you have a big system with lots of legacy code. You all know that it sucks and you all want to make it better.

You start improving small, isolated pieces of that system. You make small changes, a class here, an interface there, remove a method, clean up some function. You get the idea, you are changing code, not architecture.

This feels good, but I don’t think it helps all that much. It’s missing the big picture.

A system most likely sucks because it’s missing good abstractions and easy to understand concepts. To create good abstractions you need to make sweeping changes across your codebase.

Architecture refactoring teams

With this kind of refactoring, instead of making localized changes, you add a nice abstraction and make all the code work with the new abstraction while at the same time you remove the code that’s now made obsolete.

You refactor a bit of the system’s architecture. The goal is to improve the system not the code.

In this style of refactoring, making code changes is just a means to an end.

Let me give you an example.

Say you have some web service that receives requests and has to do a bit of processing. The current code goes straight into the processing and returns the result in the response body.

Code refactoring would keep this architecture but make the code pretty, more efficient or whatever is currently bothering you over there (maybe add some threads?).

For architecture refactoring you would need to take a step back and maybe you would replace the whole thing with a nice message queue and some worker processes that you can scale horizontally across machines.

Conclusions

I think that while the kind of code refactoring I’m talking about helps locally, it can’t really keep up with the global increase in the code’s entropy.

The architecture refactoring style takes courage and it may not be for everyone. It’s riskier than making local changes but it also brings the biggest rewards if done properly.

Also, you can easily cover your ass when you make small changes that don’t touch the system’s design. But we’re not here to cover our asses, we’re here to create great systems that work well.

Code entropy

Code entropy

I believe that a codebase has entropy. I don’t think that I am alone in my beliefs.

A codebase with high entropy will most likely manifest code rot and brittleness.

Other people like to think in terms of technical debt.

For me, the concept of technical debt is a nice way of explaining to management that while we increase the entropy for the sake of a timely release, we will have to take steps towards decreasing it in the future.

Unlike financial debt, technical debt is not well defined. It has interest, but it varies wildly and is massively dependent on the people who try to manage it.

Entropy (and technical debt) is decreased by refactoring.

Don’t confuse entropy with complexity, they are different. Entropy is just the amount of chaos in your codebase. You can have nice, clean and complex code with low entropy.

For example: Increasing entropy to fit in a last minute feature that some important client wants, will take some amount of effort. The effort to decrease the entropy to normal levels will be dependent on the total amount of entropy in the system, the people that take part in the refactoring and the amount of time since the entropy was increased.

Let me explain.

Total entropy

Every codebase contains some entropy.

The higher the entropy the weirder and harder to refactor your code gets.

I think you can actually measure the total entropy in a codebase. Do it like this:

  • Listen to your developers while they code.
  • Count the number of swear words they use.
  • Weigh the counts according to the developer’s age in the company*.
  • Sum all the counts and divide by time.

I like to think of this measure as WTFs / hour.

Yeah, this is not an objective measurement and you can’t put it in your powerpoint or talk to your manager about it. But it’s fun!

* Older developers are more important because they are used to the code. If they are surprised by something, you can bet that it’s really ugly.

People dependency

Some people are better at adding entropy than they are at removing it.

Did you ever write some sloppy code while thinking that you’ll refactor it later? Did you ever forget to refactor it and some co worker comes in and refractors it for you? Is that code now worse instead of better? That’s the guy I’m talking about.

Some developers don’t take the time to understand the code that they are working with. They don’t think about the bigger picture and what the code is trying to do. All they care about is getting it to do what they want.

Private method that looks like what I need? No problem! I’ll make it public without understanding the class it’s in.

Time dependency

This one is pretty straightforward.

The longer you wait to fix some bit of code, the longer it will take you to relearn what it does and how to fix it.

The solution

Keep your code entropy as low as possible from the start. This way you will have more stable releases, fewer bugs and you can add new features faster and cheaper.

Did you ever look at some software and learn that it has an unexpectedly large number of people maintaining it? Yup, entropy is to blame.

There is no silver bullet. Just use common sense and refactor regularly.

Oh and test your code too. Refactoring is scary without tests.

The nomad programmer

Picture of tuareg nomads in the south of Algeria.

A few days ago, I heard somebody making a remark about nomad programmers. I’ve been thinking from time to time about what it meant.

I guess a simple definition of the nomad programmer would be: one that moves from project to project.

But that is too simple, you would need to put a bit more thought into it.

My definition of the nomad programmer would be: one that moves from problem to problem.

This programmer would be in constant search of new problems to solve. He feels a rush when he solves a tough problem. That’s what keeps him going.

Nomad programmers are great if you’re a startup. When you only have problems, these are the people you want around.

Most companies can’t really handle the nomads. They either run out of interesting problems and leave or, if they try to stay, get bored out of their skulls.

Why? A startup is flexible, it doesn’t have too much bureaucracy. In a regular company, getting the solution reviewed and approved may take longer than finding it.

First I thought that being a nomad was bad, but the more I think about it, the more I start to believe that it isn’t all that bad. In the right hands, a nomad programmer is great.

Too many of them will be a pain to handle, but I think that if you can give them the proper tools and the freedom to solve your biggest problems, you’d be amazed at the results.

Using other people’s computers

picard-facepalm[1]

In an office, you often need to use somebody else’s computer, either because two people are presenting something together or even for a two person debugging session.

Whenever this happens at my computer I get annoyed with the people involved. Why? They don’t respect the proper computer “visiting” etiquette.

If you are using somebody else’s computer:

  • Don’t move their monitor or monitors in any way.
  • Don’t move or close any windows that are open when you take over.
  • Don’t log them out of any application that they may be using.
  • Don’t adjust any settings in any way.

I think that these rules are just common courtesy and they should be respected. If you need to break any of them for objective reasons, ask first.