Clean Code Notes – Functions

Notes from the book Clean Code.

  • Functions should be small. They should max 20 lines long. An ideal function should be just 2-5 lines solving only one purpose.
  • The if/while/loop blocks should be one line long, which means they should enclose another function call.
  • A function should do only one thing. One level of abstraction per function. If a function does only those steps that decompose the name of the function, it is doing only one thing and it is at one level of abstraction.
  • The Stepdown Rule – Every function should be followed by another function which is the next level of abstraction. One should be able to read the functions top-down like reading a narrative.
  • The Switch Statement –
    • cannot be reduced in size.
    • violates the Single Responsibility Principle as there is more than one reason for it to change.
    • moreover, it can grow with the addition of new conditions.
    • A Solution is to bury the switch statement in the basement Abstract Factory and let no one see it. The factory will then use the switch statement to create appropriate instances of the derivatives of the object. [ Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes. ]
  • Use descriptive names. Don’t be shy of using long names.
  • Be consistent in names, use similar phrases, nouns, and verbs.
  • Try to limit arguments. Best is no argument, next best is one argument. Multiple arguments make reading functions difficult as well as testing them.
  • Monadic functions ( functions with one argument) should always return something.
  • Diads and Triads functions are difficult to read and grasp and should be avoided whenever possible.
  • Multiple arguments can be clubbed into objects, which can reduce arguments.
  • Have function names with verbs(intent) and keywords. eg assertEquals can be changed to assertExpectedEqualsActual, which can help remove the need to remember the ordering of arguments.
  • Avoid output arguments, if the function changes the state of something then let it change the state of its owning object.
  • Return exceptions instead of returning error codes.
    • With exceptions, one can separate the error path from the happy path
    • With error codes, there is usually a file maintaining that error codes, which can change any time, making the dependencies to change as well. With exceptions, we can avoid this.
  • The code inside try-catch blocks should be moved to separate functions of their own.
  • Dijkstra’s rule of structured programming – every function should have exactly one entry and one exit, ie no break/continue/goto, and a single return statement. With small functions, we can have multiple return statements and break/continue.