Skip to main content

The Understated Importance of Clean Code

· 10 min read
Vlad Spatariu
Preparing to appease our future AI overlords.

Good code is one of the most valuable commodities in technology. Code quality can affect everything from code execution time and application load times, to how easy it is to maintain, read, and debug.

It can also play a significant role in your company's competitiveness. If your competitors are spending more time fixing bugs than adding features, then they're losing ground to you.

Clean Code is important

Two Technical terms that can save your project!

Code Hygiene goes hand in hand with avoiding Tech Debt and these two should be THE backbone of your company’s philosophy!

As you may have suspected by now, Code Hygiene starts with clean code. For developers, clean code inevitably leads to a sense of satisfaction and personal pride (especially when pushing good code to your peers for review, which is an awesome feeling to have).

For a company, however, code hygiene is infinitely more important, especially since proper clean code genuinely helps drive down costs and, when it comes down to it, this is what makes or breaks the viability of projects.

The quality of code matters. Not just because it helps us achieve our goals and build products, but also because improving code quality can be good for business. Code IS the product! So, the more scalable, efficient, and maintainable it becomes, the better it is for us all.

By the same token, poorly-written, patchy codebases can skyrocket project costs, because they become progressively more difficult to maintain. This is what is called Tech Debt.

That's why tech debt is a big deal as well. If your product developers are spending hundreds of hours wrestling with legacy code each year instead of moving your product forward, then you're wasting valuable time and money.

In a nutshell, Tech Debt is the amount you have to pay for all the shortcuts that your developers have to take to reach their deadlines, at the expense of code cleanliness.

How to Avoid Tech Debt EFFICIENTLY

Clean Code is important

  • Analyze your code carefully before making any changes to it.
  • Avoid refactoring until your code is heavily polluted with unmaintained, old and costly feature flags.
  • Let's agree not to add new feature flags until the ones we have are fully optimized.
  • Don't let clutter accumulate in crucial areas of the code. It will only make things worse for you and everyone else on the team later on down the road.
  • Occasionally take some time off from coding, to think about how you want your application to grow before you start adding more features.

How Do You Actually Keep Code “Clean”?

The answer is simple. Refactor!

It's a simple concept: clean up what you can. Add features, when you can, and refactor when you need to.

This process is iterative. You start by identifying the biggest pain points in your application and then take small steps towards fixing them. This means maintaining tight control over your application's development life cycle from writing requirements to deploying new code and providing support for time-consuming issues in production.

Refactoring doesn't mean rewriting the whole application from scratch just because one class of code got outdated. You want your code in a state where it’s easy to come back to it, understand, and build on top of it.

If your project breaks in seemingly random places as you push yet-another-feature on top of your project, then that’s a telltale sign that your product’s code is entangled, patchy, and scotch-taped together to a barely-workable state.

This isn’t just scaremongering either. There are countless cases where things get so bad that entire teams have to be rerouted to code clean up for at least a couple of sprints, and this can grind client feature requests to a halt for a seemingly horrific amount of time. This is a literal nightmare scenario for any company.

What YOU need to be aware of

The problem is that most projects end up having new features built on top of legacy code in quick succession, throughout the lifetime of the project. This is not ideal and is usually done due to time constraints.

The end result is effectively increasing your future problems for short-term gain.

This kind of entangled, hard-to-maintain code is aptly referred to as “spaghetti code" and it’s something that everyone should avoid doing as much as possible. Refactoring spaghetti code is hell-on-earth for any developer and a sure-fire way for your developers to jokingly compare themselves with Sisyphus at the watercooler conversations.

The Efforts that your Team has to make

Standardizing Individual Coding Styles is a Must!

First and foremost, your team needs to standardize around a single code-writing style and a small set of common rules, like:

  • using proper indentation;
  • avoiding the use of excess comments (while at the same time not falling into the other extreme where they don’t comment at all);
  • giving context when naming functions and variables;
  • avoiding the excess of loops in code when possible;
  • Monitoring performance changes and loading times of new features before pushing to production;

These improvements should be at the individual level and should be adopted by everyone.

Project-wide Modularity

A more practical approach, however, (rather than optimistically assuming that all developers output their best code) is to make sure that you introduce feature modularity.

What does this mean? Well, picture a big ball of multicolored yarn. That is your project's “clump” of interconnected code, and the differently-colored strings represent the interdependencies of your various project parts with one another.

What you want is as much uniformity as possible in your hypothetical ball of yarn, with each colored string organized in its own little yarn ball. In this way, if something breaks, any damage will be confined to the isolated container in which it lives, leaving your overall project free from any nasty functionality regressions.

Using Feature Flags for more Budget-Friendly Code Maintenance

Feature flags allow you to have a quick, modular, and lightweight way of deploying code in a controlled manner. In fact, one of the main benefits of splitting up your codebase as I mentioned earlier is the fact that you can hook them up to various feature flags, for ultimate control.

The idea behind feature flags is to control the release lifecycle on a per-feature basis. That way you can control when and where the new feature is enabled, for instance, you can first introduce it in your staging environment and then maybe 1-2 weeks later into production.

Proper implementation of Feature Flags is like a breath of fresh air that will help you reduce maintenance costs by "splitting" the entangled code into smaller, self-contained code pools that are easier to manage.

The Carrying Cost of Feature Flags

Not all is well and good however, because like all good things, moderation is key here.

Feature Flags shouldn’t be treated just as garlic powder, meaning that you can’t just oversprinkle your project with feature flags and call it a day. They carry a cognitive load, which means that they can also quickly make your code harder to understand if you put feature flags in just about every corner of your project. Keeping the code lean is key here, so they should only be used when absolutely needed.

Old Feature Flags Have to Go

To keep track of all of this, it’s good to organize your feature flags by their lifespan. In this way, you know what needs to be retired as your product changes and evolves. Improperly removing or simply forgetting deprecated feature flags will needlessly bloat your code and make it harder to maintain, which is the exact thing we tried to get away from.

Before removing a flag, take a look at your dependency tree and see what you depend on. Many flags are used internally in a few places - to use them without dependencies is almost impossible. However, they may not be as important as you think. If they're used by few or no code units at all, consider removing them and refactoring the affected code units instead of deleting them altogether.

You don’t want to blow up your project’s stability just because you hack at the code too aggressively. Still, this is arguably the most cost-conscious and effective way to rejuvenate and get a handle on your code again, as well as paying back a decent chunk of your tech debt in an optimal manner.

To keep track of exactly this, you could use ConfigCat’s Zombie (Stale) Flags Report (you can read more about it from the link here), which is their latest feature. This gives you the incredibly convenient ability to receive emails about what feature flags from your project haven’t been used in a long time.

Making Feature Flag Maintenance Convenient

Feature Flag maintenance needs to be something that constantly draws the attention of your developers, and for that integration with the platforms in their workflow is needed, since this makes things way more convenient and easier to pick up on and dive in.

For this, ConfigCat once again comes packing with quite a useful set of tools, enabling you to integrate your feature flags in both your Jira tickets and your Trello account, so that maintaining them always remains a forefront priority.

BEWARE of ZOMBIE Feature Flags!

Zombie cat

These are even scarier than their equivalents from the Walking Dead series. Zombie Feature Flags are pure bloat and should always be removed with surgical precision.

As a quick recap, Zombie flags are unused or poorly maintained flags in code that live on past their expiration date. These are zombies which eat away at your codebase: leaving it rotting and prone to problems.

They usually tend to get forgotten because they get removed from the dashboard but their underlying logic is not cleaned up from the code. Devs are humans too, unfortunately, and they tend to make human-like mistakes, no matter how willing and well-intentioned these coding creatures might be.

Zombie Feature Flags are dangerous

To make sure that they prevent this, I highly recommend the following tools to be used:

  • GitHub Action

    This is a handy utility that watches over ConfigCat flags in your code, their usage and validates them against your own feature flags, straight from the ConfigCat Dashboard.

  • CicleCI Orb

    Does the same as above. It eases the way you manage features and changes via ConfigCat flags without the need to redeploy code.

  • ConfigCat feature flag reference validator CLI

    A very useful tool for finding (and removing) Feature Flags that have been removed from the dashboard. The first three tools work in conjunction and complement themselves beautifully.

  • The Zombie (Stale) Flags Report

    An awesome tool that keeps you up to date with the Feature Flags that you’re not using anymore, that you know which ones to remove!

As I mentioned above, these “stale” Feature Flags can drastically add to your code’s tech debt. This tool helps you make a list of the Feature Flags that have no place in your code anymore.

If the Zombie Flags Report feature caught your eye, you can read the in-depth article about it right here.

The Bottom Line

Properly maintained code will be more maintainable, will have fewer bugs, and it will work to your advantage. So make sure that you are taking time each week to review your code over the last week to make it more organized and efficient. By employing these practices you can avoid tech debt and put yourself in a good position for future projects.

For more awesome articles like this one, make sure to check out the other articles on the ConfigCat Blog right here.