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