Software Maintenance: The Never-Ending Feud

January 25, 2018

Steps to Great Software

   Step 1. Build new software product. (600 hours)

   Step 2. Deploy excellent software product. (3 hours)

   Step 3. Fix broken, excellent software product. (10 hours)

   Step 4. Deploy fixed, excellent software product. (3 hours)

   Step 5. Add awesome feature to software product (20 hours)

   Step 6. Deploy feature of excellent, awesome software product (3 hours)

   Step 7. Add another feature to software product (35 hours)

   Step 8. Deploy feature of software product (4 hours)

   Step 9. Add yet another feature to the software product (45 hours)

   Step 10. Carefully deploy the software product (5 hours)

   Step 11. Hesitantly add another feature to that software product (60 hours)

   Step 12. Deploy sketchy feature for that software product (6 hours)

   ... and so on ...

 

I know, an odd introduction. But have you ever been through this? You've been working on a project for 2 years. And although you attempt to make your life easier by abstracting things out or adding tests, it still seems to take longer and longer to develop new features (even small ones). Even to the point where you'd rather not work on that product anymore. Or maybe, you're a rockstar developer and you simply pass off this masterpiece to someone else to maintain, just to find that they're a terrible developer and take twice as long as you do? Yea, you're probably not a rockstar...

Let's write the perfect piece of software: Everything is abstracted and everything is programmed to an interface. We use IEnumerable everywhere and there isn't a single grouping of code repeated. Everything has a "single responsibility" and functions are 5 lines of code or less. "Amazing," they all say to you. "You're super smart," they snicker, with a twinkle in their eye. You have risen above the rest, ready to work for NASA or the NSA. No one can bear to be in your awesome presence any longer for fear of being destroyed... yep... they exist.

There is no place for idealism in software development. Any dogmatic attempt to assert that something MUST be a certain way, turns into the above example where each feature gets longer and longer to develop. But hey, as long as the code is "perfect," who cares, right? I care. There are a many a expert that will tell you the "right" way to do things. But it requires wisdom to know whether they tell you "truth." Just because you hear them on a podcast or YouTube, doesn't mean they have ANY idea about what they're talking about. Heck, me included. Why should you even listen to me?

The point is, question everything someone tells you, especially if they tell you how doing "X" will save you time years down the road. It's easy to claim something that has no immediate results. Be cautious with these "experts" of software.

With that said, let me tell you what will help you years down the road.

Maintainability

There is one, and only one, primary focus that any software developer should acknowledge: the ability for software to be maintainable. Of course, correctness, functionality, and performance are all important. However, these will always be easier to address with maintainable software. But let's define maintainability first.

Maintainability: The measure of minimization to cost and risk when altering software in an effort to reduce code entropy. (Wikipedia)

Basically, when you lower the cost and risk to altering software, the higher the maintainability of that software becomes. We must actively reduce code entropy in the process, simply because increased complexity, by definition, lowers maintainability. So having "hard and fast" rules for using "X" everywhere, will make it hard to have the flexibility to create better software.

The next question everyone has at this point is simple: How do we increase a software's maintainability?

There isn't a direct answer, especially for established software. For new software, you can guard against complexity throughout the process. But with established software, patterns and architecture are stuck. These pieces of software require slow refactoring and sometimes the risk is so high, refactoring can be too dangerous to attempt.

But luckily for us, it's called "soft"ware because it can be changed. I am going to provide a couple suggestions and things you should think about when trying to make software more maintainable:

  1. Before changing a class ask, "Can I add this functionality without changing a single line of code in this class?" If this is not possible, then architecturally something is broken (open/closed principle).
  2. Always focus on Additive Programming, rather than Alteration Programming (open/closed principle).
  3. You should never have to add Unit Tests when a feature hasn't changed. If you alter an algorithm for a feature and must change the unit test, but the underlying requirement hasn't changed, then your architecture is broken.
  4. Maintainabiliy of unit tests are just as important as production code. If you find yourself changing unit tests often (non-additive), your architecture is broken.
  5. Once a coding style is established, stick with it. If the code utilizes events for extension, continue using events. If the code utilizes the decorator pattern, continue using the decorator pattern.
  6. There are always parts of software that change often (dependency root, UI, etc). Get these parts into one location. This provides a central location for "changes" to the software. Everywhere else should be additive.
  7. Re-configurability through re-compilation is expensive (because it requires new releases). When possible, allow external configuration mechanisms to allow quick changes to the operation of software. This allows for developers to stay uninvolved.
  8. Bugs occur. When this requires changes to existing classes, only add unit tests for the bug. No current unit tests should change.
  9. Use mature libraries. These tend to have extensive documentation. If its out there, don't re-write anything you don't have to. Maintainability, in general, means adding new features. The more custom software you have, the more chances for bugs and issues. Mature libraries are tested by 100s, 1000s, or millions of hours of development time.
  10. Good architecture tends to be more like an Onion, rather than layers of a cake. Keep the lowest level details at the inner circle of the onion and work outwards (reference).
  11. Default to Private Classes and Methods. Only make them public when it is required. This reduces the possible use of code from unintended purposes.

This list is not exhaustive, but it can give you some things to think about. Ultimately, your focus should be to phase out your job on that software product. When you're not needed anymore, the software can be deemed a success. This means your software is working and you get to move on to bigger and better things.

Note: This, obviously, assumes that you're not kicked OFF the team for such terrible programming practices.

I know it can be hard to see how to create maintainable software from these steps. I will create other articles on how to do this and what it looks like later. But for now, good luck, and God speed!

Back to blog

Related Posts

Check out our thoughts here.

What is important to a career

Lately I’ve been spending a lot of time thinking about my career and where it’s going. I don’t want to give the impression that I have never thought about my career before, but now the thoughts are becoming constant.

May 8, 2018
Databases: Component or Infrastructure?

There is always strong debate around databases and their role in development. Sometimes they are considered components, while others will consider them infrastructure. Is there a right answer? Let's discuss!

March 15, 2018
Software Maintenance: The Never-Ending Feud

There is one, and only one, primary focus that any software developer acknowledge: the ability for software to be maintainable. Of course, correctness, functionality, and performance are all important, these will always be easier to address with maintainable software.

January 25, 2018