Simplicity is Hard

Simplicity is one the values of Extreme Programming. Simplicity is hard.

To achieve simplicity you need to be able recognize the presence or absence of simplicity.

Perhaps more than anything you need a strong desire for simplicity.

Once you have achieved simplicity don’t be surprised when you show your code to your colleagues and they react with a Looks right. Why would you do it any other way?

While I find this kind of reaction personally disappointing, it means that I’ve achieved simplicity.

Refactoring to Simpler Code

Here is some code from my current project:

public boolean isAllowedToAddAdministrators() {
   boolean retVal = false;
   SecurityRole currentUsersSecurityRole =
       getUiContext().getUser().getSecurityRole();
   if (currentUsersSecurityRole.equals(SecurityRole.SYSADMIN)) {
     retVal = true;
   }
   return retVal;
}

I’m going to refactor it to this:

public boolean isAllowedToAddAdministrators() 
   return loggedInUser().isSysAdmin();
}

Did you just think to yourself Looks right. Why would you do it any other way?

Refactoring Steps

Here is that same code from my current project:

public boolean isAllowedToAddAdministrators() {
   boolean retVal = false;
   SecurityRole currentUsersSecurityRole =
       getUiContext().getUser().getSecurityRole();
   if (currentUsersSecurityRole.equals(SecurityRole.SYSADMIN)) {
     retVal = true;
   }
   return retVal;
}
The first thing I notice is that the code seems unnecessarily complicated. It’s written using a structured code style that is not warranted in this case. Essentially, isAllowedToAddAdministrators() uses a condition to assign to a boolean return value. Instead, I can just return the condition.

Apply Simplify Boolean Logic.

public boolean isAllowedToAddAdministrators() {
   SecurityRole currentUsersSecurityRole =
       getUiContext().getUser().getSecurityRole();
   return currentUsersSecurityRole
       .equals(SecurityRole.SYSADMIN);
}
The code doesn’t feel right. I often use inlining to gain a fresh perspective.

Apply Inline Temp to currentUsersSecurityRole.

public boolean isAllowedToAddAdministrators() {
   return getUiContext().getUser().getSecurityRole()
       .equals(SecurityRole.SYSADMIN);
}

The code still doesn’t feel right, although, you could argue that it is as simple as it could be.

Whenever I have to read code like this I find it hard to tease out the intention: I’m thrashing about in nothing but implementation details. I think I can make it simpler by extracting some little methods.

Apply Extract Method to getUiContext().getUser() to create loggedInUser().

public boolean isAllowedToAddAdministrators() {
   return loggedInUser().getSecurityRole()
     .equals(SecurityRole.SYSADMIN);
}

private IUser loggedInUser() {
   return getUiContext().getUser();
}
Apply Extract Method to loggedInUser().getSecurityRole().equals(SecurityRole.SYSADMIN) to create isSysAdmin().

public boolean isAllowedToAddAdministrators() {
   return isSysAdmin(loggedInUser());
}

private boolean isSysAdmin(IUser loggedInUser) {
   return loggedInUser.getSecurityRole()
       .equals(SecurityRole.SYSADMIN);
}

private IUser loggedInUser() {
   return getUiContext().getUser();
}
Often when I see code of the form someFunction(anObject) I want to transform it to the form anObject.someFunction(). This procedural-style to object-style heuristic is telling me that I should move the isSysAdmin() method to the User class.

Apply Move Method to isSysAdmin().

public class SecurityPolicy {
 
  public boolean isAllowedToAddAdministrators() {
     return loggedInUser().isSysAdmin();
  }

  private IUser loggedInUser() {
    return getUiContext().getUser();
  }

}

public class User implements IUser {
 
  public boolean isSysAdmin() {
    return securityRole.equals(SecurityRole.SYSADMIN);
  }

}

Where did I end up?

I refactored the isAllowedToAddAdministrators() method

public class SecurityPolicy {
 
  public boolean isAllowedToAddAdministrators() {
    boolean retVal = false;
    SecurityRole currentUsersSecurityRole =
        getUiContext().getUser().getSecurityRole();
    if (currentUsersSecurityRole.equals(SecurityRole.SYSADMIN)) {
      retVal = true;
    }
    return retVal;
 }
 
}

first to

public class SecurityPolicy {

  public boolean isAllowedToAddAdministrators() {
    return getUiContext().getUser().getSecurityRole()
        .equals(SecurityRole.SYSADMIN);
  }
 
}

and then to

public class SecurityPolicy {
   
  public boolean isAllowedToAddAdministrators() {
    return loggedInUser().isSysAdmin();
  }

  private IUser loggedInUser() {
    return getUiContext().getUser();
  }

}

public class User implements IUser {

  public boolean isSysAdmin() {
    return securityRole.equals(SecurityRole.SYSADMIN);
  }

}

So, how exactly is where I ended up simpler? Why didn’t I stop the refactoring after the first step?

Two Simplicity Heuristics

Two simplicity heuristics that I use are the Telephone Test and a preference for Little Methods.

To perform the Telephone Test you attempt to read your code to someone over the telephone. If the person on the other end does not understand what you are talking about, then you need to rewrite your code.

Little Methods are short methods, named by what they are intended to do, not how they do it.

The final version of isAllowedToAddAdministrators() is a Little Method that passes the Telephone Test.

public boolean isAllowedToAddAdministrators() {
  return loggedInUser().isSysAdmin();
}

I can imagine this exchange:

Q: When does the application allow administrators to be added?
A: When the logged in user is a SysAdmin.

How does the Telephone Test work for this code?

 public boolean isAllowedToAddAdministrators() {
   return getUiContext().getUser().getSecurityRole()
      .equals(SecurityRole.SYSADMIN);
 }

Q: When does the application allow administrators to be added?
A: When the UI Context user’s security role is equal to SysAdmin.

Code readability is so important: my programming speed is way more limited by my ability to read and comprehend code than it is by my ability to type code.

When I created isSysAdmin() on the User class I created a Little Method:

public boolean isSysAdmin() {
  return securityRole.equals(SecurityRole.SYSADMIN);
}

Notice how when I had finished refactoring I’d created 3 single line methods. This style of coding requires well chosen names that reveal intent. Poor names will force the reader to mentally inline each of the Little Methods.

So why do I like to code with lots of well-named little methods? Because in code, as in life: If you do something and you do it well, you will be asked to do it over and over.

Leave a comment

Your comment