Improve your Code by Refactoring to Nouns and Verbs

To quote the refactoring pioneer, Martin Fowler:

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Improving the readability of your code will enhance its usability for your future self and for other developers. In this post I’ll teach you a technique I use when programming that will make your code read more like English. When your code reads more like English, you will need fewer comments to document your methods. Instead of explicitly writing comment blocks that describe what a method does, you will express those comments in the way you name your methods and in the way you compose your method calls.

The basis of this refactoring technique is to think about your methods in terms of nouns and verbs. Noun methods return items to work on and verb methods perform operations on noun items. Each type of method should have a meaningful name that is itself a noun or a verb. In addition, adding prefixes like in and suffixes like of to method names can make your code read even more like English.

Time for an example.

In this post I’ll use a JavaScript example that uses jQuery to show and hide a search box user interface element. However, the code is very simple and you won’t need any experience with jQuery to follow along. Also, I’ll use the terms method and function interchangeably because this refactoring technique is applicable to any language with a function- or method-like language feature.

The search box is a HTML input element:

<input id="search-box">

Let’s start with a function that hides the search box by adding a CSS class called hidden, which is defined as:

.hidden {
  display: none;
}

Adding this class to a HTML element will hide the element and removing this class will show the element.

The hideSearchBox function adds the hidden class to the search box by selecting the search box element with its ID using the jQuery selector $("#search-box") and then calls the jQuery addClass function on the search box element:

function hideSearchBox() {
  $("#search-box").addClass("hidden");
}

The companion method showSearchBox shows the search box by removing the hidden class from the search box element:

function showSearchBox() {
  $("#search-box").removeClass("hidden");
}

These two functions implement verbs (hiding and showing) on a noun (the search box element). Let’s start by factoring out the hide and show verbs into their own functions

function hide(element) {
  element.addClass("hidden");
}

function show(element) {
  element.removeClass("hidden");
}

We can then write the hideSearchBox and showSearchBox functions as:

function hideSearchBox() {
  hide($("#search-box"))
}

function showSearchBox() {
  show($("#search-box"))
}

Now we can factor out the search box element selector into its own noun function:

function searchBox() {
  return $("#search-box")
}

We can then rewrite the calls to hideSearchBox and showSearchBox from

hideSearchBox()
showSearchBox()

to

hide(searchBox())
show(searchBox())

Now that we’ve factored out the noun and the verbs, we’re starting to build up a language in our program for handling HTML elements. It’s now easy to show and hide other HTML elements by first creating a new noun function to return the element and then using the result of the new noun function as the parameter of the show or hide verb functions.

Let’s look at another example where we can refactor a function that converts its single parameter from milliseconds into seconds.

function inSeconds(milliseconds) {
  return (milliseconds / 1000)
}

Although this function is pretty clear—it converts milliseconds to seconds by dividing by 1000—it contains the magic number of 1000. In other situations, the meaning of a magic number might not be obvious so we would document it with a comment. However, we can remove the need for the comment by refactoring the magic number into its own value function, millisecondsPerSecond:

function inSeconds(milliseconds) {
  return (milliseconds / millisecondsPerSecond());
}

function millisecondsPerSecond() {
  return 1000;
}

By moving the magic number into its own function we’ve made the inSeconds function crystal clear. Also, since the body of the millisecondsPerSecond function is a single return statement, there is no need to document it further; the name of the function documents the return value of the function.

By creating self-documenting value functions like millisecondsPerSecond, you can also avoid cluttering your classes with instance variables, which also makes your code more readable. Additionally, wrapping values in functions enables you to override them in subclasses.

Notice the in prefix of the inSeconds function above? Prefixing function names with prepositions like in and of also helps to build up English-like function calls. Another example of this is the toggleAnimationOf function below, which uses Of to connect the toggle verb with the element being toggled:

function toggleAnimationOf(element, animationDuration) {
  
}

Using the techniques I’ve shown you so far, we can build up more complex function calls that still reads very naturally:

toggleAnimationOf(searchBox(), inSeconds(searchBoxAnimationDelayInMillis()))

function searchBoxAnimationDelayInMillis() {
  return 500;
}

Summary

By renaming your methods and functions as nouns and verbs and by refactoring your method and function calls, you can improve the usability of your code by making it easier to read by your future self and other developers. As a reminder, here are the noun and verb functions we used in this post:

Nouns Verbs
searchBox()hide()
millisecondsPerSecond()show()
searchBoxAnimationDelay()inSeconds()
toggleAnimationOf()

Finally, although I call this a refactoring technique, with practice you will be able to write code using nouns and verbs from the beginning.

Learn More

When you build up a language of methods and functions within a program, you’ve created an internal Domain Specific Language (DSL).

Learn more about improving your code by refactoring and how to write better code the first time round in Clean Code by Bob Martin.

blog comments powered by Disqus