Clean Code: Writing Code for Humans

coryWelcome to this review of the Pluralsight course Clean Code: Writing Code for Humans by Cory House.

Cory is a Microsoft MVP in C#, founder of OutlierDeveloper.com, avid tech reader, and speaker. He believes in clean code, pragmatic development, and responsive native UIs.

When I produced my list of the Top 10 Pluralsight courses in 2015, this is one of the courses that very narrowly missed the top 10. Learning how to write clean code is one of the most important things that you can do as a developer, and that is what this course is all about.

In addition to watching this course, I can highly recommend Robert Martin’s book Clean Code and also Code Complete by Steve McConnell

Cory’s course is the third course in the Getting to Great with C# Learning Path, but developers familiar with any C-like language (VB.NET, Java, JavaScript, Objective C etc.) should be able to follow along without any problem.

As I write this review I am re-watching it for the first time in nearly 3 years. This course was developed after Cory began giving talks on Clean Code, as you can find out more about both the course and his talks on his own site Bit Native.

Introduction

Introduction

Cory explains that this course is all about writing code that is easy for our fellow developers to read, maintain and understand. A couple of quotes that inspired Cory and can also inspire you are this one from Donald Knuth:

“Programming is the art of telling another human what one want a computer to do”

and this one from Martin Fowler:

“Any fool can write code that computers understand. Good programmers write code than humans can understand.”

Cory discusses the meanings and takeaways of these quotes.

Why should I care?

Cory explains that writing code is easy but reading code is hard, discusses the negative effects of technical debt, and reminds you that you never want to become a verb!

The Foundation

Cory explains the Clean Code is a foundation for the SOLID principles. There is a course from Steve Smith on the SOLID principles later on in the Getting to Great with C# Learning Path.

The SOLID principles not only help your code to be more, maintainable, they also help your code to be more unit testable. So these principles can be viewed as a foundation for unit testing. I have written a guide Learning Unit Testing and Test Driven Development to help you decide which course(s) to watch to learn those practices.

Cory mentions that Steve Smith’s course on refactoring is yet to be published. This course has been published and it features on my list of Top 10 Pluralsight courses.

There are at least a couple of good Domain Driven Design courses available as well, which is something that builds on your refactoring skills. But first you must learn clean code.

We are Authors

Cory runs through some definitions of authors. As developers, we meet all of these definitions.

We learn that the techniques traditional writers use to make their writing easier to understand translates to what we do as developers. The only difference is the jargon.

Resources

Cory House recommends three books. The first two are the ones I recommended above. The 3rd is the Pragmatic Programmer, a book that I still haven’t bought or read, despite it being recommended many, many times.

Principles

Three Core Principles

Cory describes the three core principles of clean code. The first one is…

The Right Tool for The Job

All developers have their favorite tools, but a common mistake is for developers to get carried away and use their new toy in situations that aren’t appropriate.

Here Cory illustrates this with a time that he “creatively” used the wrong tool for the job.

Boundaries Matter: Stay Native

Cory discusses the boundaries between HTML, CSS, JS, server side languages  (Ruby/C#/Python) and SQL. It explains the need to stay within them, and the price that you pay if you don’t.

I know that Cory has since slightly revised his opinion on the boundary between JS and HTML, a hell of a lot has happened on the client in the past 3 years.

But the key points here remain. Stay within your boundaries, understand where they are and respect them.

Cory gives 7 advantages for staying native.

Potential Evil

Here Cory gives three examples of useful technologies that turn evil when they are used beyond the area where they were originally designed to be used for.

There are many more examples that you should be able to think of. Be aware of the area where any particular technology is strong and stay within it. I think that this is an extremely important point.

Signal to Noise Ratio

Cory explains TED as an acronym for signal (good) and tells us that there are many bad practices that contribute to noise.

DRY Principle

Don’t Repeat Yourself. The point that I most strongly agree with here is that copy and paste is often a design problem.

Cory discusses some issues that duplication creates.

Self-documenting Code

A study that was done way back in 1979 but remains true today found:

“Understanding the original programmers intent is the most difficult problem” Fjelstad & Hamlen

Cory describes four core things that self-documenting code strives for.

Naming

Naming Matters

This is an example of dirty code due to bad naming, and then see the clean version.

The only change is an improvement to the naming, but the difference in readability is striking.

Classes

This shows a number of examples of bad class names.

I almost laugh out loud, because I have seen almost every one is these bad class names over the years, and you will likely have seen them as well.

Cory provides several guidelines for good class names. We see the first specific reference to one of the SOLID principles here.

Methods

Method names should be specific and give the reader a good understanding of what the method does without needing to read all of the program logic within it.

Cory lists many examples of bad names, and some much better ones.

Rubber Ducking

ruberduck

You might wonder whether Cory has completely lost his mind as he recommends putting a rubber duck on your desk so that your explain your code to it.

There are however real benefits in doing this! In my office, there is no rubber duck, but there is a toy frog.

His name is Reginald. Reginald the frog. As well as being interested in all of our coding problems, he serves as a reminder to us to do our stand ups.

Warning Signs

Words like And, Or, If in your method names suggest that your method is attempting to do more than one thing.

Side Effects

Some examples of method names and what they should not do as well.

Abbreviations

The80s

The 1980s were awesome. All of the abbreviations were a lot less awesome.

Hey remember the 80s? What’s up rat fans! Turtle power! I have the power! All those TV shows. Ah, memories!

Booleans

Boolean names should sound like they are asking a true/false question, and we some examples of those that do and don’t here.

Symmetry

Names for opposites should be opposites. Cory discusses some of the almost opposites, and contrasts them with the clarity of good symmetrical naming.

Conditionals

Boolean Comparisons

“Which would you say in real life? If logged in equals true? Or if logged in?”

Boolean Assignments

Chipotle

I don’t know about you, but this clip is making me hungry.

It’s also a reminder on how you can simplify your boolean assignments and increase your signal to noise ratio.

This is another good example of the power of reading out code in English. The redundancy jumps out at you, prompting you to eliminate it.

Positive Conditionals

Don’t be anti-negative! Just the name “anti-negative” sounds strange – why not just say “positive”? Why not write conditionals positive?

Ternary Elegance

The ternary operator is another opportunity to increase our signal to noise ratio.

Cory discusses the balance you should strike with the use of the ternary operator: not too much and not too little.

Stringly Typed

I love this name “Stringly” Typed. Sounds like Strongly Typed, but then wait, it’s NOT Strongly Typed.

Strongly Typed beats Stringly Typed, Cory gives four very good reasons why it is better to use an Enum.

Magic Numbers

Avoid magic numbers because they make the intent of your code much harder to understand.

Complex Conditionals

Another code smell here. Cory describes some techniques for refactoring the smell away:

  • Intermediate Variables
  • Encapsulate complex conditionals in a well named method

Although it is usually better to write less rather than more code, the example that Cory gives for encapsulating complex conditionals shows that there are times when it is necessary to write some additional code to clarify intent.

Polymorphism vs Enums

Here we see a dirty switch statement and a cleaner solution using the Template Method pattern.

Be Declarative

We see some of the benefits of learning LINQ here.

Something I either completely missed or forgot the first time I watched this course is Cory lists LINQ like implementations available languages other than C#:

  • JavaScript: jLinq
  • Java: LambdaJ (Java 8+ has it’s own implementation of Lamdas so I guess LambdaJ is  obsolete now)
  • Python: Pynq

Table Driven Methods

Here we see an example of dirty code that would be much more suited to existing in a database table.

Functions

When to Create A Function

Cory gives several reasons for creating a new function. The first one is to…

Avoid Duplication

We return to the DRY principle, and Cory explains that less is often more.

Ironically this is one clip that could have been eliminated as we’ve already covered this earlier in the course, however it’s important to understand that this principle applies to functions as well as other forms of code.

Excessive Indentation Overview

Cory introduces us to arrow code, which makes me shudder as it reminds me of some hideous code I wrote many years ago.

Cory refers to a study by Chomsky and Weinberg:

“Comprehension decreases beyond three levels of nested ‘if’ blocks”

The next three clips discuss refactoring solutions to this problem. For a more in depth guide to refactoring, scroll down to number 6 in my list of Top 10 Pluralsight courses.

Also, if there is dirty code in your organization’s applications, consider starting a Refactoring Forum.

Extract Method

Cory likens this practice to an author using footnotes and shows an example from Wikipedia.

Extract Method is one of the most common and valuable refactorings.

Return Early

This clip references a great piece of advice from the book Code Complete:

“Use a return when it enhances readability… In certain routines, once you know the answer…not returning immediately means that you have to write more code.”- Steve McConnell

Fail Fast

Cory explains the concept of guard clauses here, and where they are useful.

I sometimes think of this as “offensive coding” as opposed “defensive coding”.

Aside from the readability issue, I have seen a lot of code that tries to prevent the program from crashing at all costs and in the process makes a set of database or other state changes before the true coding error comes into light via an exception in a part of the application far away from the actual coding error.

It is important to learn defensive coding, but it is also important to know when you should fail fast.

Make sure that you also watch the exceptions clip in the Functions module to understand this point.

Convey Intent

We see the complex conditionals example again, so that we can appreciate that the clean version of it better conveys the intent of the code. This more than justifies the extra code required here.

Do One Thing

Cory explains that there are many advantages of functions only doing one thing:

  • Aids the reader
  • Promotes reuse
  • Eases naming and testing
  • Avoids side-effects

Mayfly Variables

The lifetime of a mayfly is extremely short: only a few hours, and many live for less than an hour!

Not covered here is the thorny issue of JavaScript variables. Because of hoisting many people recommend declaring all of your variables at the top of your functions.

It is important to understand hoisting in JavaScript. As long as you and your team understand it, you should be free to code in the style that you like best.

Parameters

Cory explains that we should strive for only 0 to 2 parameters in each function.

Also covered here is some good advice on watching out for flag arguments.

What’s Too Long?

Here Cory describes 5 signs that a function has grown too long:

  • Whitespace / Comments
  • Scrolling
  • Naming issues
  • Multiple conditionals
  • Hard to digest

This clip also refers to the book Clean Code, and the specific advice that functions should be rarely be more than 20 lines of code and hardly ever more than 100 lines of code, and have no more than 3 parameters.

Cory also refers to the Linux style guide and simplifies it to an important maxim.

I think that this is very smart thinking because I have seen a few examples of long but very simple functions that are much more readable than they would be if there would be if they were broken out into multiple functions just to satisfy some arbitrary or inflexible coding standard on the maximum length of a function.

Exceptions

There are three kinds of exceptions:

  • Unrecoverable
  • Recoverable
  • Ignorable

Cory explains the you should process these kinds of exceptions in different ways, and gives the important advice not to catch exceptions that you cannot process intelligently.

Classes

When to Create

Cory discusses many situations where it is appropriate to create a new class:

  • New concept
  • Low cohesion
  • Promote reuse
  • Reduce complexity
  • Clarify parameters

He explains the benefits of creating a new class in each of these situations

Cohesion

This clip explains the concept of high cohesion, which was first introduced by Tom De Marco in 1979.

Cory contrasts this with some of the magnet classes that were discussed in the Naming module.

As an example we see that a magnet Vehicle class is much better split out into three classes:

  • Vehicle
  • VehicleMaintenance
  • VehicleFinance

Cory stresses that you should start with a good, specific class name, and that usually leads to higher cohesion.

When is a Class too Small?

Signs that a class is too small are:

  1. Inappropriate intimacy
  2. Feature Envy
  3. Too many pieces

Steve Smith’s Refactoring Fundamentals course goes into a lot more detail in these areas.

Cory adds that it is very rare for classes to be too small, so be more concerned about classes that are too big.

Primitive Obsession

Primitive obsession is using primitive types such as strings and integers instead of encapsulating model classes.

Cory explains 4 advantages of creating a new class here.

Also see Mark Seemann’s From Primitive Obsession to Domain Modelling

Principle of Proximity

This is all about making code easy to read from the top of the file downwards, and Cory discusses keeping related actions together.

Outline Rule

Collapsed code should read like an outline. This is a tricky concept to grasp initially, so there is a demonstration later in this course.

Comments

Introduction

Cory asks the question “Are comments great, or a code smell?” and gives the answer “Yes there are!”

Necessity and Crutch

Comments are both a necessity and a crutch, and here Cory gives general rules on when and when not to use comments.

Next we look at some types of comments to AVOID.

Redundant

Redundant comments break the DRY principle because they are a form of repetition

Intent

These explain what the code intends to express. Much better if the code itself expresses this.

Apologies and Warnings

Cory describes this as malpractice and he is right. Instead of apologising, fix the issue.

Zombie Code

Yay! Kill Your Zombie Code!

Cory discusses the common causes of zombie code: risk aversion, and hoarding mentality.

Next he explains how zombie code damages your signal to noise ratio, creates ambiguity, hinders debugging and refactoring, and adds noise to searches.

KILL YOUR ZOMBIE CODE

Dividers and Brace Trackers

Back in my old VB.NET days when text editors were very primitive and I before LINQ was invented, I used to use brace trackers (end if trackers?) nearly all the time.

Modern text editors and IDEs will now highlight matching opening and closing braces for you, and brace trackers should never be required these days. If you see them, remove them.

Bloated Header

Another hideous “best practice” from an earlier era in programming. Ghastly! Thankfully source control is pretty ubiquitous today, and bloated headers are becoming a much rarer sight.

Defect Log

Avoid comments that only describe source control metadata because that’s exactly what source control is for.

Clean Comments

I have seen TODO comments plenty of times before, but never seen HACK comments before.

I recommend avoiding TODO comments unless you have specific processes in place around them, e.g. we cannot go live with TODO comments in place. They are only useful if they are very temporary. As Cory says, you should standardize as a team.

In a previous job, there were around 250 TODO comments in the codebase from many years ago. Nobody could remember or tell which if any were still relevant, but nobody wanted to delete them either just in case they were important. I expect that most of them still live on in the codebase today.

Other examples of clean comments that Cory describes are summary comments and documentation that can’t be expressed in code.

Demo

In this module, Cory takes a dirty application and refactors it into a clean one using the principles covered earlier in this course.

It is an application for registering conference speakers and Cory registers his cleaning fish for humans course.

We see that the initial dirty code is a fairly realistic and not too exagerrated example.

Some problems with it are:

  1. Much too much indentation
  2. High cyclomatic complexity, low maintainability index and high class coupling
  3. Numerous types of useless comments
  4. Poorly named variables
  5. Variable declared to far away from their use

Cory fixes all of these problems and turns the application into something much cleaner.

Stay clean

This final module wraps up the course by examining the key takeaways.

First he discusses when, and when not to refactor. Most importantly you need adequate test coverage to protect yourself against regressions.

Next he relates the Broken Windows article to coding and the lessons that teaches us.

He recommend Code Reviews and/or Pair Programming (two best practices that I strongly agree with)

He points out Robert C. Martin’s “Boy Scout Rule”:

“Always leave the code you’re editing a little better than when you found it.”

And he ends with a summary of all these important points.

Verdict

Must Watch.

2 thoughts on “Clean Code: Writing Code for Humans

  1. Pingback: Getting to Great with C# Learning Path | Zombie Code Kill

  2. Pingback: Building Applications with React and Redux in ES6 | Zombie Code Kill

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s