The broken windows theory from criminology applies to source code: If a code base has a bunch of inconsistencies and quality problems, we will take that as the norm and continue the pattern. Here are four things you can do to avoid broken windows in your code, and set a norm of quality and craftsmanship.
1. Name Consistently
Each language has its own idioms when it comes to naming variables: snake case, camel case, and kebob case. Find the case that is idomatic to your language and stick to it. This gets tough to do around architectural boundaries, such a REST APIs. Ultimately it doesn’t matter, but define a standard and stick to it.
Also, throw out the idea of using Hungarian notation since a well-named variable will innately contain that information. For example, a variable named
strFirstName is pointless when
firstName is sufficient. We do not expect a first name to be a boolean or any other type. Do not be afraid of long variable names either. If you get stuck and can not find a good name for a variable, do not be afraid to use a thesaurus.
2. Apply Single Responsibility to Functions Too
The single responsibility principle applies to functions just as well as classes. Functions should be really good at doing one thing; this makes the much easier to test, name and understand. The general rule of thumb that I go by is functions should not be longer than 10 lines. Just remember, rules are meant to be broken, but only with a good reason.
If you have a mega-function that you want to break down, loop and selection structure bodies are good candidates for abstraction. This is a nice representation of single responsibility: one function to walk the data structure and another to parse single records.
3. Write Self-Documenting Code
Comments are fine and have their purpose, but keep in mind that they add unnecessary lines to maintain. They can’t be tested and therefore can not be trusted like code. Write code in such a way that you will understand it when you have to come back to it. This has a lot to do with small functions, well-defined test suites, and well-named variables.
Comments should be reserved as cliff notes to those coming behind you. Do not be afraid to write an apology to your future self if you have to settle for a janky solution. Feel free to explain architectural decisions, weird bugs that can not be reproduced, and TODOs. Document liberally, but only when it adds value.
4. Have a Well-Defined Interface
With small functions, a lot of them will be reserved for a class’s internal use only. Put thought into the design and step back occasionally to look at the big picture of your object. These are not easy questions, but you should be frequently asking yourself:
- Does this function need to be exposed outside this class?
- Does this function belong here?
- Are there similar functions that smell the same as this?
- Should I create a new class for this?
Staying true to test driven development is a good way to define a decent interface, but the same questions should still be running through your mind.
What tips and tricks do you have for code quality? What is the best and worst code that you have seen?
More on Code Quality
Want to learn more? Here are a few other Atomic Spin posts on code quality: