I loved this presentation by Neal Ford. The first practice it mentions is the composed method implementation pattern. I think this is one of the most most fundamental coding patterns I can think of. In this post I would like to talk about it.

It was originally described in Kent Beck’s book Smalltalk Best Practice Patterns. In this book, Beck says that:

Compose methods out of calls to other methods, each of which is at roughly the same level of abstraction

I used to refer this pattern as factorized code. The first time I realized about its importance was reading Martin Fowler’s Refactoring book. I remember being very impressed by Fowler’s coding style. In the extract method refactoring pattern the book said that, when you have in your code something like this:

void someMethod(){ 
  //do some stuff
  line 1
  line 2
  line 3

  //calculate some other stuff
  line 4
  line 5
  line 6

  //do final stuff
  line 7
  line 8
  line 9
}

You should refactor it to something like this:

void someMethod(){ 
  doSomeStuff();
  calculateSomeOtherStuff();
  doFinalStuff();
}

void doSomeStuff(){ 
  line 1
  line 2
  line 3
}

void calculateSomeOtherStuff(){
  line 4
  line 5
  line 6  
}

void doFinalStuff(){
  line 7
  line 8
  line 9  
}

Instead of having a sequence of comments and chunks of code, you should extract those chunks to methods with proper names. This way you could also remove comments, as they would be redundant.

Dividing high-level routines into calls to lower-level ones was a common design practice in the old days of Procedural programming. With Object Oriented Programming, I think many people only care about designing the public contract of objects and their relations. While that is obviously very important, the internals of every method should be carefully designed too.

Although this pattern may seem very simple, applying it correctly is not as simple as saying you should divide methods into small steps. I think there are three fundamental properties that should rule methods design:

  • Cohesion
  • Clear interfaces
  • Symmetry

Methods should be highly cohesive. This means that methods should do only one thing, from the point of view of the caller. Who is the caller depends on the abstraction level where the code is being invoked. Could be another class o just a private method inside in the same one.

Methods should have clear interfaces. In Writing Solid Code Steve Maguire says that the signature of all methods (functions in those days) should be clear enough in order to understand what the method does. Signature means the name of the method as well as of the parameters it receives and returns (and their types). Achieving this involves many things but without cohesion is just impossible.

The book shows a good example of how a method should not being designed: the C realloc() function. It just does many things with a very obscure interface. The book also includes a nice metaphor from the physical word, the candy machine interface problem: when candy machines offer numbers for both selecting products and displaying their prices. Methods should not offer a candy machine interface.

The composition of methods should also be symmetric. The steps a method is divided in should be at the same level of abstraction. Abstraction is a construction that a person does in order to understand something. Jumping from one level of abstraction to another requires mental effort. If you have to keep jumping between different levels of abstraction in order to understand some code, it will be far more difficult to understand.

I think this pattern improves code quality immensely. In my opinion, it also makes tackling complex problems easier. It is the principle of divide and conquer working. I usually code methods following a top-down approach. Writing the top level methods calling lower-level methods before they exist. This way I can translate the structure of steps I have in mind directly into the code.