Skip to content

Instantly share code, notes, and snippets.

@cbefus
Last active April 20, 2018 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbefus/9ac31a6822b8531abf425fefb92c55b4 to your computer and use it in GitHub Desktop.
Save cbefus/9ac31a6822b8531abf425fefb92c55b4 to your computer and use it in GitHub Desktop.
An improved version of Listing 2-2 in Clean Code By Robert C. Martin
import com.google.common.collect.ImmutableMap;
import java.util.function.BiFunction;
/**
* @author Chad Befus
* This is my attempt at an improvement on Listing 2-2 of "Clean Code" by Robert C. Martin
*/
public class GuessStatisticMessage {
public final char candidate;
public final String number;
public final String verb;
public final String pluralModifier;
private static ImmutableMap<Integer, BiFunction<Integer, Character, GuessStatisticMessage>> conditionalBuilders =
ImmutableMap.of(
0, (count, candidate) -> new GuessStatisticMessage(candidate, "no", "are", "s"),
1, (count, candidate) -> new GuessStatisticMessage(candidate, "1", "is", ""),
2, (count, candidate) -> new GuessStatisticMessage(candidate, Integer.toString(count), "are", "s")
);
private static int DEFAULT_BUILDER_KEY = 2;
private GuessStatisticMessage(
final char candidate,
final String number,
final String verb,
final String pluralModifier
) {
this.candidate = candidate;
this.number = number;
this.verb = verb;
this.pluralModifier = pluralModifier;
}
public static GuessStatisticMessage fromCountAndCandidate(final int count, final char candidate) {
return conditionalBuilders.getOrDefault(count, DEFAULT_BUILDER_KEY).apply(count, candidate);
}
@Override
public String toString() {
return String.format("There %s %s %s%s", verb, number, candidate, pluralModifier);
}
}
/**
* @author Robert C. Martin
* This is Listing 2-2 of "Clean Code" by Robert C. Martin
*/
public class GuessStatisticMessageOriginal {
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 = "no";
verb = "are";
pluralModifier = "s";
}
}
@cbefus
Copy link
Author

cbefus commented Apr 4, 2018

I argue that this is better because:

  1. There is an obvious way to construct this using a named static method (and still only one way to do so).
  2. We can easily add new cases to the map (imagine a different case for the number 3) and also easily change the default functionality.
  3. We now have an Immutable object representing the collection of values extracted from count and candidate that can be used as more than just a String.
  4. This object can be used as a string because it overrides the toString() function of java's base object.

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