Graduate Program KB

Clean Code

Chapter 3

  • Enforce the single responsibility principle

    • Functions should be small, very small
    • Functions should perform one task
    • Functions with many lines are harder to understand, test and maintain
  • Blocks and indenting as a result of condition statements and loops make code harder to read. These nested structures can be extracted into new functions to improve readability

  • Functions should be organised such that the reader can follow the code without jumping around too much

    • Avoid goto, continue and break whenever possible
  • Each function should manage only one level of abstraction, don't mix tasks with vastly different operational details

    • For example, lower-level tasks such as constructing the URL string should not be mixed with the higher-level task of sending a HTTP request
    • Furthermore, functions should be read top-down, so higher-level functions should be declared below lower-level functions, where details become more complicated as a result of abstraction
    • The progressive code should tell a story
  • Switch statements can often be replaced with polymorphism which is cleaner and more maintainable. Also, using this structure usually indicates a variety of tasks are handled at the same scope which violates the single responsibility principle

  • Similarly to what was discussed in the previous chapter, function names should be descriptive and meaningful

  • Functions should have as few arguments as possible

    • None or one argument, easier to understand
    • Two, gets a bit more complicated
    • Three, can become very complex, could be performing multiple tasks in the function or the arguments are often related enough to be passed as an object
  • Functions should have no side effects, they should be pure. For any input, we expect the exact same output every single time

  • Functions should perform an action or return a value, not both

    • For example, finding the total cost of a list of products then also updating the UI with the new value in the same function is not ideal
  • Functions should throw errors when encountering an error, not return error codes

    • Errors can be thrown and handled in separate functions
    • Returning error codes makes us have to deal with the problem immediately and the type of error is usually determined through a large conditional structure
  • Duplicate code should be avoided, refactor the common task into a single function