Practical Code Refactoring, Part 1 – What is Good Code?

This entry is part 1 of 4 in the series Practical Code Refactoring

Practical Code Refactoring

Refactoring is about re-thinking your code, everything in it, for the sake of making your code better. In this series on code refactoring, I’ll show you the Why, When, What, Where, and How of refactoring since refactoring is more of an art more than a science. In this part I’ll explain what makes code good, the basis which I build upon later through the rest of the series.

What is Good Code?

The main goal of refactoring is clean code, better code, or whatever you might call it. But what actually constitutes good code? Good code is smelled and tasted. If you’ve written a lot of code, you understand what I mean; you can easily identify whether code is good or bad with experience. But what if you are new to coding but still want to do things right?

We can summarize the aspects of good code with these three guidelines:

  • Readable
  • Extensible
  • Efficient

Readability

When your code follows some standard well-known syntax, style, and documentation practices, or in other words when you and your development colleagues can easily interpret the code with minimal ambiguity, your code is said to be readable and consequently maintainable in terms of style and appearance. To achieve this, you should follow a coding standard. You may use some public standard or create your own if you like, but whichever you choose, your colleagues should find your syntax, style, code documentation, and comments straight forward, clear, and require no further explanation as much as possible. I prefer using a public standard since it can shorten the learning curve for new people joining my development team later.

Readability and extensibility overlap when you use basic constructs of your programming languages for what they were intended as much as possible, and for solving well-known problems you use well-known patterns (design patterns). But what if you have a new problem? Or what if you’ve just crafted a better solution for an old problem? Terrific! Other programmers won’t be able to understand your new billion dollar solution if you don’t document it properly! Keep your mind working at its best and flying as high as you like, but remember to take the time to describe inside your code how and why you made it.

Extensibility

Both readability and extensibility contribute to the maintainability of your code and overlap at certain times. But to sharpen the difference, readable code is maintainable in terms of its style and extensible code is maintainable in terms of its logic. The same argument applies to design patterns since they contribute to both readability and extensibility.

Your code is extensible when it follows some re-usable, logical, well-known patterns, be it defined standard design patterns or normal logical flow. For example, some developers favor using the Singleton design pattern for working with database connections. As another example, most of us would use a standard foreach to iterate over an array, which is a standard flow. One might use a for loop or even a while loop under similar circumstances, but this is fairly uncommon in PHP so it should be documented why such constructs were necessary foreach to avoid confusion.

The major aspects of extensibility are decoupling and encapsulation. Decoupling means that your code (mainly functions/methods and classes) shouldn’t depend or overlap each other; code should be as “pure” as possible, with any overlapping functionality and other non-related entities removed. If you are writing procedural code, your functions should only contain the logic that their names imply; don’t make functions do too much! Use a “toolbox” approach when writing code – small basic routines work together to build big complicated systems.

Encapsulation is an integral part of decoupling. Whenever you decouple components, you have already done some encapsulation. To encapsulate components, continue separating its internals from the global scope and make all interactions with it occur at its interface level. This is a modular approach which makes it easier to later remove or update any part of your system as opposed to a monolithic design which makes your code spaghetti.

Efficiency

You should keep efficiency in mind from the very first line of code in any project since bottlenecks are known to come from some very unwise usage of language constructs, for example nesting several loops and using recursion unwisely, and from some unwise usage of logical patterns, for example not making use of caching and sending/receiving data to/from streams without proper buffering.
Efficiency is important, but don’t compromise the first two rules for the sake of it. In fact, compromising readability and extensibility can actually result in less efficiency! For the majority of cases, efficiency is directly proportional to applying the first two rules. When there is an exceptional situation, do your best to make sure you have other ways of keeping your code good.

Summary

In this article I introduced you to what makes code good. I limited the discussion to three major aspects: readability, extensibility, and efficiency, and described what each means.

Now that you know what constitutes good code, we can move on to the next parts in the series. In part 2 I’ll show you some things to be on the look out for when refactoring for better readability.

Image via Fotolia

Practical Code Refactoring

Practical Code Refactoring, Part 2 – Readability >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Dina

    Could you be lil more specific about “Readability”? Can you give me example of public standard?

    Thx

    • Kyle

      I believe that PSR-1 is becoming the new “standard” across open source PHP frameworks. But following a specific convention isn’t an important as following *some* convention. The best way to tell if your code is readable is to ask another programmer to read your code. I think it’s generally considered good practice to have verbose variable names. For example, don’t litter your code with $x and $i when those represent something tangible (obviously that’s okay for arbitrary loops, points, etc). But if you have an object called “duck”, don’t instantiate it into a variable called “$d”. Just call the variable “$aDuck” or “$myDuck” or something similar. Doing this will make your variable instantly understandable no matter where the developer is viewing it within the flow of the application. Also, try not to leave too many comments in your code. Comments should explain “why” you’re doing something (“had to use thisFunction() because otherFunction() didn’t execute in constant time”), not how. Your code is the “how”, and it should explain itself.

      Besides that, common syntax like indenting code blocks, being consistent with casing (try not to mix naming conventions, i.e. naming one variable “$my_variable” and the next one “$myOtherVariable”; same with your functions.

      If you’d like more examples, the PSR standard is probably a good place to start looking.

  • Bado

    Do yourself a favor and get a copy of Robert C. Martin’s book Clean Code (http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ref=sr_1_1?ie=UTF8&qid=1350076243&sr=8-1&keywords=Clean+Code). It should be required reading for every developer, regardless of how many years of experience they have.

    • Abdullah Abouzekry

      Totally agree, but not all has the time to do so, hence this article :)

      Best