Skip to content

Instantly share code, notes, and snippets.

@gonutz
Created May 29, 2025 13:58
Show Gist options
  • Save gonutz/7c824582411b470b8292fac7cf282fe6 to your computer and use it in GitHub Desktop.
Save gonutz/7c824582411b470b8292fac7cf282fe6 to your computer and use it in GitHub Desktop.
Cleaner Code

Cleaner Code

In Robert C. Martin's 2008 book Clean Code there is a code example in the chapter Meaningful Names, in subsection Add Meaningful Context. The purpose of the code is to print guessed characters in a game, like this:

There are no Xs
There is 1 Y
There are 23 Zs

Original BAD Code: 22 lines, 490 characters

private void printGuessStatistics(char candidate, int count) {
	String number;
	String verb;
	String pluralModifier;
	if (count == 0) {
		number = "no";
		verb = "are";
		pluralModifier = "s";
	} else if (count == 1) {
		number = "1";
		verb = "is";
		pluralModifier = "";
	} else {
		number = Integer.toString(count);
		verb = "are";
		pluralModifier = "s";
	}
	String guessMessage = String.format(
		"There %s %s %s%s", verb, number, candidate, pluralModifier
	);
	print(guessMessage);
}

After this follows the book's improved version, stating: The improvement of context also allows the algorithm to be made much clearer by breaking it into many smaller functions.

Clean Code's BETTER Version: 40 lines, 820 characters

public class GuessStatisticsMessage {
	private String number;
	private String verb;
	private String pluralModifier;

	public String make(char candidate, int count) {
		createPluralDependentMessageParts(count);
		return String.format(
			"There %s %s %s%s",
			verb, number, candidate, pluralModifier );
	}

	private void createPluralDependentMessageParts(int count) {
		if (count == 0) {
			thereAreNoLetters();
		} else if (count == 1) {
			thereIsOneLetter();
		} else {
			thereAreManyLetters(count);
		}
	}

	private void thereAreManyLetters(int count) {
		number = Integer.toString(count);
		verb = "are";
		pluralModifier = "s";
	}

	private void thereIsOneLetter() {
		number = "1";
		verb = "is";
		pluralModifier = "";
	}

	private void thereAreNoLetters() {
		number = "0";
		verb = "are";
		pluralModifier = "s";
	}
}

(Note that the line verb, number, candidate, pluralModifier ); is the actual formatting used in the book.)

What I would like to see:

Actual READABLE Code: 9 lines, 250 characters

private void printGuessStatistics(char candidate, int count) {
	if (count == 0) {
		printf("There are no %ss", candidate);
	} else if (count == 1) {
		printf("There is no %s", candidate);
	} else {
		printf("There are %d %ss", count, candidate);
	}
}

Note that I use an imaginary printf function that might have to be created. The alternative would be three print(String.format(...)) which would clutter the code. Apart from that I would say my final version of the code is very similar to what someone just learning how to program would write. The good thing about novices is that they do not know how to create an object-oriented mess like the Clean Code one. Plus they usually are more interested in achieving a goal instead of focussing on "architecture".

What is wrong about the book's "better" version?

  • It is more code overall. This makes it more code to read and maintain.
  • A single, simple task is broken up into a class with five methods. To understand it we actually need to jump around a lot. The context is hard to keep in your head this way.
  • The call site gets polluted as well. Instead of
    printGuessStatistics('A', 5);
    
    the caller now has to say
    print(new GuessStatisticsMessage().make('A', 5));
    

It is pretty much worse in every way imaginable. I do not know why this example is in the book. Because...

Although complaining about one of its examples, I highly recommend reading Clean Code. I have spent two projects applying everything it taught me. Test-Driven Development (TDD) was an eye-opener. All the rules on good names and comments, all the advice on architecture are really valuable. Did you know that Clean Code exists in video form?

Nowadays I rarely use TDD (that is writing tests to drive the API). My functions are not tiny and I use names that fit in 80 columns, even if they are not as descriptive as they could be. TODO comments appear throughout my code whenever I want to remind my future self of something. All of these I was told in the book are bad, they are not clean.

Why do I sound ambivalent? Because every piece of advice, especially a book with a lot of advice, has its good and bad parts. Clean Code changed the way I write code. I kept what worked and dropped or modified the rest. In programming you need to try things out and see what works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment