Light Bulb Methods

By Gerald Mücke | June 27, 2018

Light Bulb Methods

While writing the article on “How to write good code”, I used the term “light bulb methods” and I want to explain bit more in detail, what I meant with this style of method structuring.

Imagine a light bulb. Lightbulbs typically hang down from the ceiling. So when you start top-down - like the execution flow of a method - you first wind down along the screw thread, followed by a glass bulb containing the glow thread.

The screw thread is not the most important part of the light bulb but it serves an important auxiliary function: It should ensure the lightbulb fits into it’s socket and adheres to the specification of the input.

Attached to the screw thread is the light bulb containing the glow thread. The glow thread and it’s fixation is clearly visible, there is not much complexity around it so it becomes obvious what its doing by merely looking at it.

The glow thread is surrounded by a glass bulb containing a protective gas to avoid the glow thread from oxidation and to give enough space for fallout that could happen during operation. The glass itself could be coated to for different lighting results.

So how does this refer to code of a method?

  1. Screw Thread
    • check parameters and arguments first, fail or return fast
    • transform the parameters as needed
    • have visual separation to the actual logic of your method
  2. Glow Thread
    • keep the core logic of the method concise and clear
    • concentrate on a single responsibility, don’t put too much logic in one place
    • simple code usually perform better out of the box and is easier to check
  3. Glass and Coating
    • keep the core logic visually separated from the rest of the method (evacuate)
    • add exceptions handling if needed at the end of the method. Either transform & rethrow exception or handle them (this includes logging), but not both. (fallout)
    • add sensible logging or tracing to track business processing but don’t add cross cutting concerns like security, transaction handling or input/output logging to the method itself, use interceptors, aspects or wrapper methods instead (coating)

The following method is an example for searching an array linearly.

One note on the log statement: I put it there to to illustrate the “coating” aspect and is just by coincidence the same as the return value. The comments could be removed, I put them there to clearly indicate the three sections

public int findPositionInArray(String[] array, String element) {
    //screw thread: fail and return fast
    Objects.requireNonNull(array, "Array must not be null");
    Objects.requireNonNull(element, "Element must not be null");
    if(array.length == 0) {
        return -1; 
    }
    
    try { //part of the glass bulb
        //glow thread
        int pos = -1;
        for(int i = 0; i < array.length; i++) {
            if(array[i].equals(element)){
                pos = i;
                break;
            }
        }
        
        //glass and coating
        log.debug("Found the element after {} iterations", i)
        return pos;
    } catch(NullPointerException e) {
        throw new RuntimeException("Array structure invalid, containing null value");
    }
}
comments powered by Disqus