How to write clean code?
This article covers:
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.
Read other posts
comments powered by Disqus