Qualities of a good function

Methods/functions are fundamental elements from which the whole application is built. Therefore, to reach high quality software code, we need high quality functions that have these qualities:

  • do one thing

A function should do one thing. Yes, SRP also applies to methods/functions. If a function does one thing, it is simple, clear, easy to understand and easy to test. Great. How can it be tested? For example: if you can’t name a function correctly, it means that it does too much.

How to call this function?

???? (Customer customer) {
    customer.name = customer.name.toUpperCase();
    save(customer);
}

Is this method does one thing? How to test it?

One thing does not mean one line of code. No. This means many lines as needed to fulfill this one thing.

  • easily testable
  • visible state change

If you see this declaration of method

xxxx (Customer customer)

you expect that some of the properties are taken from customer parameter, and you do not expect that customer will be changed, but if you see

Customer xxxx (Customer customer)

you expect that customer was changed, and you should use the returned object.

So, if you encounter this code

void setCustomerNameAsUppercase (Customer customer) {
   customer.setName(customer.getName().toUpperCase());
}

Prefarable way is:

Customer setCustomerNameAsUppercase (Customer customer) {
      customer.setName(customer.getName().toUpperCase());
      return customer;
}
  • name the power be with you
  • the same level of abstraction

A function should contain code at the same level of abstraction. What does this mean? In one function, we do not want to mix business/high-level code with technical/low-level code. Why is this important? Because for our brains, switching between high-level abstractions and details is a nightmare. In fact, it is context switching.

Let’s see some examples:

void badFunctionThatMixLevelsOfAbstractions () {
  //low-level code - technical details
  String query = "SELECT * FROM users WHERE id = " + userId;
  String userData = dbConnection.executeQuery(query)
  //high-level code - business rules
  int scoring = user.income - user.outcome * 40%;
}
void goodLowLevelAbstractionCode () {
  db.startTransaction();
  String query = "SELECT * FROM users WHERE id = " + userId;
  String userData = dbConnection.executeQuery(query)
  dbConnection.executeUpdate("update ..")
  db.endTransaction();
}
void goodHighLevelAbstractionCode (User user) {
   scoring = getUserScoring(user);
   financeReport = getFinancialReport(user);
   financeReport.calculateCreditLevel(scoring);
}
  • number of parameters

Our brain, short-term memory, can store a maximum of (approximately) four elements. Just four elements! Therefore, an ideal function signature should contain a maximum of four elements:

void validateCustomer (Customer customer, Address address, int age);
          1                    2                  3             4

Customer customerNameAsUppercase (Customer customer, bool onlySurname);
    1                2                    3                 4

Summary

You should really care about the quality and clarity of the functions, because the whole application is built from them.

Leave a Reply

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