Function

FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.
  • Ideally, a function should be less than 15 ~ 20 lines.
  • Describe the function by describing it as a brief TO paragraph: "To ..., we have firstly ..., then, ..."

Check our previous example in Session 1.

Sections within Functions

If one function is divided into sections like declarations, initializations, and sieve. It's wrong.

Again, functions should do one thing.

One Level of Abstraction per Function

  • Mixing levels of abstraction within a function is always confusing.

Reading Code from Top to Bottom: The Stepdown Rule

  • Connect with "TO paragraphs".
  • Vertical distance of function definitions.

Use Descriptive Names

  • You know, it's important.
  • Don't be afraid to make a name long.

Function Arguments

  • Less is better.
  • Arguments are even harder from a testing point of view.
  • The function and argument should form a very nice verb/noun pair.

Have No Side Effects

  • Side effects are lies. Your function promises to do one thing, but it also does other hidden things.
public class UserValidator {
    private Cryptographer cryptographer;
    public boolean checkPassword(String userName, String password) {
        User user = USerGateway.findByName(userName);
        if (user != User.NULL) {
            String codedPhrase = user.getPhraseEncodedByPassword();
            String phrase = cryptographer.decrypt(codedPhrase, password);
            if ("Valid Password".equals(phrase)) {
                Session.initialize();
                return true;
            }
        }
        return false;
    }
}

Can you find the effect side in this function?

Prefer Exceptions to Returning Error Codes

When you return an error code, you create the problem that the caller must deal with the error immediately.

if (deletePage(page) == E_OK) {
    if (registry.deleteReference(page.name) == E_OK) {
        if (configKeys.deleteKey(page.name.makeKey() == E_OK)) {
            logger.log("page deleted");
        } else {
            logger.log("configKey not deleted");
        }
    } else {
        logger.log("deleteReference from registry failed");
    }
} else {
    logger.log("delete failed");
    return E_ERROR;
}

But, if we use try/catch:

try {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
    logger.log(e.getMessage());
}

Don't Repeat Yourself

Duplication may be the root of all evil in software.