Graduate Program KB

Functions


Key Takeaways

  • Functions should do one thing and do it well.
  • They should be short.
  • Have well described names so it is clear what they do (a verb)
  • Arguments should be nouns
  • Functions shouldn't really have more than 2 arguments:
    • Niladic: takes no arguments is ideal
    • Monadic: takes one argument, should only be used if altering the argument and returning it or returning information about the argument.
    • Dyadic: takes two arguments, should usually be avoided. A good use case as an example is a 2D coordinate function.
    • Triads: takes three arguments, hard to understand and test for (due to the different combinations). Should be avoided and usually can be.
      • Often multiple arguments are related and can be combined into an object. For example rather than passing in an x and y coordinate, why not pass them in as a Point object.
  • Flag arguments are problematic, passing a boolean into a function instantly flags that the function is doing more than one thing. If true do this, else do this.
  • A function shouldn't have side effects, a side effect means that the function is doing something else that isn't told or obvious in order to do its task.
    • Example in book is initializing a session to validate a password. Initializing the session isn't really told explicitly so you could be unaware that you're starting a new session when you want to validate a password. This could lead to you losing your current session data.
  • Indent level of a function shouldn't be greater than 1 or 2.
  • A function should either do something or answer something, not both.
  • We prefer exceptions over error codes.
  • Remember that we want a function to do one thing, and Error Handling is one thing and hence needs its own functions, etc.
  • One level of abstraction per function.
  • We want to extract try and catch blocks and use same principles when error handling. See example below and how it can be improved:
try {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
}
catch (Exception e) {
    logger.log(e.getMessage())
}

Above is doing too much, let's make it better:

public void delete(Page page) {
    try {
        deletePageAndAllReferences(page);
    }
    catch (Exception e) {
        logError(e);
    }
}

private void deletePageAndAllReferences(Page page) throw Exception {
    deletePage(page);
    registry.deleteReference(page.name);
    configKeys.deleteKey(page.name.makeKey());
}

private void logError(Exception e) {
    logger.log(e.getMessage());
}

Return