Consistency == Maintainability

I think I can categorically say that the most important thing I’ve learnt about software engineering is that consistency is the most important thing in software engineering that leads to something being maintainable. It’s something I feel very strongly about.

If you have awful code or non-standard concepts in your code then as long as you apply the awful code or concepts consistently across your application then as soon as anyone that needs to maintain that code gets their head around what’s going on they can maintain the code effectively. It comes down to readability and comprehension. The quicker and easier it is for someone to read a code snippet and understand what is going on (no matter how badly it makes their eyes bleed) the easier it is for them to identify problems and introduce a fix.

I’m not saying that writing best practice code and using principles like DI, DRY and YAGNI aren’t going to make something maintainable because they do and they are critically important when you are developing software! What I am saying though is they don’t have as big an impact on maintainability as consistency. Furthermore, from a pragmatic perspective, sometimes you inherit code that wasn’t written with best practice¬†approaches¬†and you need to maintain it; yes you could spend a whole heap of time rewriting it, but at the end of the day as long as it’s consistent then it’s maintainable and there may well be more valuable uses of your time.

It does raise an interesting question though about refactoring. If you do have a crappy codebase you have inherited and you decide it will deliver value to do a major refactor then it’s important to ensure that you refactor in a way that leaves the codebase in a consistent state!

11 Replies to “Consistency == Maintainability”

  1. You make some very good points (as always). I’ve worked on some horrible code and find the easiest way out is often the best using the same (bad) style. When I refactor I just get a barrage of questions from others who don’t get it.

    1. I still think its really important to refactor bad code while maintaining something – in particular if it’s a part of the code that takes up a lot of support time. I just think its important to ensure that if you are changing something that you make that change consistently across the code base rather than leaving it in an inconsistent state.

      With the example you gave – if you are able to do the refactor and prove that it makes the code more maintainable then as long as that change propagated through the entire code base so the existing way is no longer there then the other people supporting the code will eventually get used to the change and understand it. Obviously, it’s important that they buy in to the consistency above all else approach and any new code they add in is consistent with the new way of doing things or you end up with an inconsistent mess.

  2. I worked at a gov org in Australia with a horrible horrible codebase. Every single class was public static and obviously no unit tests as their design was untestable. No need to say that the system was bug-ridden. That said they had a brilliantly consistent codebase – every bit of code you looked at followed the same horrible pattern and looked just as shit as the next one.

    I got a bug assigned to me that had been reported two month before and two devs had spent weeks on it and released a patch that not only didn’t completely fix the bug but it also introduced two more bugs!! I got in the code, put in some integration test around the mess, refactored their code and made it unit-testable, put in some 30 unit tests around the broken code, found and fixed the three bugs and two more bugs that hadn’t been found before which I reported, confirmed and fixed. I committed the code. The team lead came to me pretty pissed off after he reviewed my code and asked me to either fix the code following the existing patterns if I can or revert my changes. After some argument, I was forced by the manager and the team lead to revert my code, and I spent two days to fix their code using their broken patterns because they didn’t want their consistency touched. I worked there for a few months and sneaked good code every time I could. When I left most of them were writing better code with proper unit tests. Their code was no longer consistent but was more readable and maintainable – at least the new inconsistent code was.

    So as much as I think consistency is important I would pick a good inconsistent code over a broken consistent code every day of the week.

    1. Hey mate,

      Great comment!

      *disclaimer* Obviously it’s easy for me to sit back from an armchair and give my thoughts on the situation and it’s possible that the situation was not conducive to what I’m describing below */disclaimer*

      As I hinted to Wilson above, I still think fixing bad code is really important and you shouldn’t let consistency stop you doing that. In saying that, you can let consistency and Agile practices like focussing on the most important thing / retrospectives help you when dealing with that kind of situation. What I mean by this is, you can look at the codebase and identify that the largest pain point at any point in time for maintenance is (such as a particular pattern that is used, or area of the code or set of tests etc.). It’s important to get team buy-in at this point to avoid the problem you faced; if the team doesn’t play ball at all and aren’t interested in continuous improvement then there isn’t a code problem, but rather a people problem to focus on.

      Once you have identified the most important thing to deal with then you can work together as a team to find a mutually agreeable way to make the problem better (or remove it completely if possible) – avoiding massive code changes by breaking it up into stages that start simple is a good technique I like using for this type of thing. As long as you make the effort of applying that fix consistently across the codebase and then move on the the next most important thing then I think that’s ideal in terms of keeping consistency, but allowing refactoring/change/evolution.

      Sometimes it takes a long time to propagate a change so that can be tricky. To that I would say two things:

      • sometimes you just need to be pragmatic and say “I accept this inconsistency because the alternatives aren’t feasible” e.g. it’s not going to work to keep with the existing/broken approach or spending the time propagating the new way of doing things across the codebase
      • It’s OK if it takes a little time to propagate as long as it does get propagated (team discipline required), the team gets trained to use the new way exclusively from now on and moves to the new way when touching old code that doesn’t conform

      There is a really great post from Jimmy Bogard that goes further into this that I identify with: http://lostechies.com/jimmybogard/2013/10/08/evolutionary-architecture-boundaries/

  3. To clarify my point, I think consistency is very important; but not necessarily through out the codebase and with old code. I think it’s very important for the whole team to follow a consistent pattern that is not set merely to keep the codebase entirely consistent but to make the codebase more maintainable even if that means checking in code that’s inconsistent with old code. When the whole team follows the same consistent coding pattern the code will reach eventual consistency.

    1. Eventual consistency is the key here, but it’s important to not let it get out of hand and make sure the team is diligent and disciplined about reaching that eventually consistent goal (but this requires buy-in).

Leave a Reply

Your email address will not be published. Required fields are marked *