Clean Code 101: Functions

Computers can do 2 things: store data and do things with data. Functions are what we do and describe actions we take with the data we already have (or want to create).

Consider this code:

public static String networkRun() {
     //Code here
}

Can you figure out what this function is trying to do? Probably not.

This is because we literally just violated what I said to do above. Functions should be verbs.

The function above has no details and it communicates zero intent.

public static String startNetworkAndBeginSetup() {

}

By turning out function name into a verb, it visually looks more pleasing, follow convention, and more precisely communicates what we are trying to ask.

Do one thing

This is actually way harder to do then you might think. Consider the function we just refactored. Is this function doing one thing or three things? The three things are one level abstraction below the stated name of the function.

If a function does only those steps that are one level below the stated name, the function is doing one thing.

Robert Fowler – Clean Code

This may seem obvious, but too much abstraction can be bad too. Most developers “follow the code” and having webs and webs of abstractions (spaghetti code) can be hell.

Code should read like a book

Code should read like any document (including this one). We want every function to be followed by those at the next level of abstraction. Essentially, we want to be able to read the program as though it were a set of nested paragraphs that begin with To and make logic sense being next to each other.

To include the network start, then we begin iterating over ip block
     To include iterating over ip block, then init ping

Use Descriptive Names

Previously we changed the name of our function to startNetworkAndBeginSetup. This is far more descriptive and better describes what the function does.

The overall goal is to provide the most context in the least amount of words.

Function Arguments

The ideal number of arguments for a function is zero. Next comes one, two, three, etc. More then three arguments is considered pushing the limits and requires special justification.

Passing only one argument

There are two common reasons to pass a single argument into a function.

1. You may be asking a question

boolean stockExists("TSLA");

2. You may be operating and returning something.

Stock getStock("TSLA");

There are values people expect and perfect examples of wonderful functions.

Events

A useful single argument function can also be an event! In this form there is an input argument, but no output. The code is simply meant to interpret function call as an event and alter the system.

void injectCodeIntoDOM(code) {
    //This event is occuring outside and altering the system
}

Flag Arguments Are Bad

Passing a boolean into a function is bad practice. It immediately complicates the signature of the method and makes the function only do one thing.

To avoid flag arguments, the simple thing to do is just make separate functions.

Have No Side Effects

Even though I am a Java/.NET developer, I’m still a huge believer in functional programming. Having no side effects means function only doing one thing. Side effects can cause unexpected changes outside your function.

public class NetworkManager {
    private Database _db;

    private boolean isUserAuthenticated(String username, String password) 
        User user = _db.find(username);
        if(user) {
            Session.addCookie();
            return true;
        }
        return false;
    }
}

In our case, the side effect is Session.addCookie() because our function never said anything about initializing a session. This side effect also creates temporal coupling. Temporal relates to time and this function is indeed time sensitive. If temporal coupling exists, you should make it clear in the name or comments, ie; isAuthenticatedOnLogin().

Leave a Reply

Your email address will not be published. Required fields are marked *