This is a quick review of some important parts of the book “Clean Code: A Handbook of Agile Software Craftsmanship” by Robert C. Martin.

Advantages of clean code

  • Better use of your time: Code is read a lot, you forget things, so clean code helps you quickly grasp what the code did.
  • Easier onboarding: Getting co-workers up to speed is much easier if the code base is clean.
  • Easier debugging: Others can help you out, since the code is understandable, even non-programmers like a project manager might be able to spot things.
  • More efficient maintenance: Adding new features is much easier in a clean code base.
  • Confidence: You can show your code to others without being totally ashamed ;)

Clean Code Principles

“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”

– Martin Fowler

General guidelines

  • KISS - keep it simple stupid. Always strive do do things as simple as possible rather than trying to look smart with unnecessary complex code.
  • Follow standard conventions in your team and your programming language community.
  • When you see unclean code, try to fix it right away, especially if it is a quick edit away.
  • When there is a problem, always find the root cause of it, rather than just “fixing” it.
  • Be explicit rather than implicit. If you make assumptions, others (and even yourself) might not get them over time.

Write for humans, not machines

  • Name your variables, functions, classes etc very carefully, so you can read the code like a book.
  • Don’t use abbreviations, but rather pronouncable names.
  • Try to make semantic sense, e.g. no user.createUser(), but rather user.create() method.
  • Show your intentions with naming rather than explaining them with comments, e.g. var daysSinceCreation; rather than var dsc; // days since creation
  • Be simple rather than creative in naming, use your creativity for the logic of the program.
  • Be consistent: don’t use delete() in one object and remove() in another, rather stick to one naming.

Functions

  • Make functions short.
  • A function does one thing.
  • A function has a small number of arguments (3 is a lot!)
  • There should be no side effect when executing a function.
  • Don’t use boolean flags or other flags, rather create separate methods.

Comments as refactoring hints

“Of course, bad code can be cleaned up, but it’s very expensive.”

– Robert C. Martin

  • Let the code explain itself rather than to use comments to explain what is happening, e.g. when you have a complex if clause and you are tempted to write a comment to explain it, then put the if clause in a boolean method which has a proper naming. See for yourself, what is easier to read in the upcoming example?

    if vehicle.has_four_wheels() and vehicle.has_motor() and vehicle.get_weight() <= MAX_CAR_WEIGHT: # sell all cars: a car should have four wheels, a motor and weigh no more than 3500kg
    sell(vehicle)
    

vs.

if vehicle.is_a_car():
    sell(vehicle)
  • No redundancy, i.e. don’t write as a comment what is already clearly laid out as code.
  • Don’t use closing bracket comments - your IDE should help you figure out which bracket belongs to which.
  • If you comment code parts, don’t check that into git, but rather delete it.
  • Use comments to explain your intent when necessary, but again always strive for refactoring first.
  • Sometimes a comment is nice to explain code if you cannot refactor it, e.g. when a library you are using has a weird naming or sth. like that.

Code structure

  • Related code is close together, e.g. don’t declare a variable and then use it much later.
  • When a function uses another function, they should also be close together.
  • Try to keep lines short.
  • Don’t align horizontally to have the code look nicer - it is harder to read!

On tests

  • Stick to arrange, act, assert and have one assert per test.
  • Keep the tests readable.
  • Tests should be repeatable, i.e. always have the same outcome.
  • The execution of tests has to be fast and automatic, otherwise they won’t run often enough.
  • Tests should be independent of one another.

On Objects

  • Stick to the hiding principle: do not expose internals.
  • Use data structures where appropriate, i.e. where you do not need special manipulation methods.
  • Don’t create so-called hybrids: half object and half data, i.e. don’t create an object which can get into an invalid data state by calling some methods in some order etc. To circumvent, create a data object, which takes care of handling the data and exposes methods which always ensure that the state of the data is valid.
  • Do one thing (there is a pattern here).
  • A parent class should not know anything about its children.
  • Prefer non-static methods over static methods.

Further tips

  • Obviously use source control, i.e. git. When doing so, there is no need to check in commented out code - just remove it, you can always get it back with git.
  • Don’t repeat yourself - DRY priciple.
  • Don’t hardcode values, but use a constant which is referenced wherever the value is in need.
  • Use code reviews with your colleagues, e.g. using Gitlab or Gerrit
  • Consider test-driven development (TDD) to more easily create clean code from the beginning
  • Together, decide for code conventions and then stick to them. To help you do so, use a linter.