Code Quality and Maintenance
Programs must be written for people to read, and only incidentally for machines to execute. — Harold Abelson, Structure and Interpretation of Computer Programs
Maintenance takes up about 70% of the total software lifecycle and a large portion of the overall costs. This means that we spend more time reading than we do writing code. When code is easy to understand, it is also easy for other developers to efficiently analyse, debug, and extend.
This article explores readability as a means for improving code quality and maintenance.
What Is Readability?
According to this research by Todd Sedano, it takes almost 4 times as long to review hard-to-read code. However, an encouraging two-thirds of the programmers surveyed wrote easy-to-read code by default. To improve readability across the board, we first need to understand what it is.
Readability is a means of assessing code quality based on factors such as the:
Formatting of code, including indentation, spacing, letter case, etc.
Naming of variables, functions, classes, etc.
Nesting levels of conditionals and loops
Complexity of a function, including its length and the number of parameters it accepts.
These are not the only factors to consider but they provide a good starting point for assessment. Readability is considered one of the key metrics of software quality, and it is probably the most straightforward way to evaluate and improve code quality.
Example Guidelines to Improve Readability
The following code snippets are in Ruby but a majority of the guidelines are transferable to other programming languages. Let's dive in!
1. Use two spaces per indentation level
# hard
def some_method
do_something
end
# easy
def some_method
do_something
end
2. Write one expression per line
# hard
puts 'foo'; puts 'bar'
# easy
puts 'foo'
puts 'bar'
3. Use a space before and after operators and after commas, colons, and semicolons
# hard
sum=1+2
a,b=1,2
class FooError<StandardError;end
# easy
sum = 1 + 2
a, b = 1, 2
class FooError < StandardError; end
4. Leave an empty line between function definitions
# hard
def some_method
do_something
end
def some_method
do_something
end
# easy
def some_method
do_something
end
def some_method
do_something
end
5. Do not use space for method calls and bracket access
# hard
print (x + y)
some_collection [index_or_key]
# easy
print(x + y)
some_collection[index_or_key]
6. Leave an empty line between method calls
# hard
def some_method
data = initialize(options)
data.manipulate!
data.result
end
# easy
def some_method
data = initialize(options)
data.manipulate!
data.result
end
7. Do not use empty lines around class, function, and other built-in statement bodies
# hard
class Foo
def foo
begin
do_something do
something
end
rescue
something
end
end
end
# easy
class Foo
def foo
begin
do_something do
something
end
rescue
something
end
end
end
8. Align or indent by two spaces, the arguments of a method call if they span more than one line
# hard
def send_mail(source)
Mailer.deliver(
to: 'bob@example.com',
from: 'us@example.com',
subject: 'Important message',
body: source.text)
end
# easy
def send_mail(source)
Mailer.deliver(to: 'bob@example.com',
from: 'us@example.com',
subject: 'Important message',
body: source.text)
end
# easy
def send_mail(source)
Mailer.deliver(
to: 'bob@example.com',
from: 'us@example.com',
subject: 'Important message',
body: source.text
)
end
9. Avoid the use of nested conditionals for control flow
# hard
def compute_thing(thing)
if thing[:foo]
update_with_bar(thing[:foo])
if thing[:foo][:bar]
partial_compute(thing)
else
re_compute(thing)
end
end
end
# easy
def compute_thing(thing)
return unless thing[:foo]
update_with_bar(thing[:foo])
return re_compute(thing) unless thing[:foo][:bar]
partial_compute(thing)
end
10. Add underscores to large numeric literals
# hard
num = 1000000
# easy
num = 1_000_000
The above examples are adapted from the Ruby Style Guide and are by no means an exhaustive list. Check out the main style guide for your programming language to get a more specific and complete list.
All is well that ends ...
The benefits of readability cannot be overstated. It could result in huge cost and time savings and play a key role in the outcome of a project.
The good news is there are several tools that help with writing easy-to-read code. Code editors now have in-built support for common guidelines, and linters can be used to enforce a particular style guide. So, the next time your annoying linter flags up a violation, take a deep breath, smile, and remember the bigger picture... then fix it!
Thanks for reading! Let others know you found it useful by sharing and dropping lots of emojis. All comments are welcomed.
Until next time... keep calm and carry on writing quality code!