Skip to content

Latest commit

 

History

History
86 lines (59 loc) · 3.59 KB

clean_code.md

File metadata and controls

86 lines (59 loc) · 3.59 KB

Clean Code

These are mostly notes from the classic "Clean Code" by Uncle Bob.

Names

Use meaningful variable/function/class names.

  1. Don't use magic constants. Always make a variable. Easier to refactor later!
  2. Use descriptive names: userPhone, customerId.. Don't make me guess!
  3. Don't prefix interfaces with I, e.g. IMyService.. Why should a user care that it is an interface???
    That's the whole point of interface, to abstract away the details
  4. You can use single-letter name but only in a narrow context, lambda or a for loop..
  5. Don't encode type in the name, e.g. userString... We have compilers now!
  6. Be consistent! If you used UserRepo::findByName(), don't make UserRepo::getByEmail().. it's confusing and rude! :D
  7. Avoid redundant information! If you have class UserRepo, why would its method be called findUsers() and not just find()?
    We already know it is a user repo!!

Functions

  1. Do one thing!
  2. Smaller - the better!
  3. Less parameters - the better! (make a class for grouping them! bonus: easier refactoring)
  4. Avoid side effects
  5. Keep the same level of Abstraction in a function!
    If you're talking about cars, you shouldn't suddenly jump to atoms!
    Same with controller->regex-parser e.g.
  6. If you side-effect, don't return a value; If you query, don't side-effect! (command-query separation)
    Although Java violates this one regularly, e.g. int remove(Object o)
  7. Minimize use of switch statements. Preferably only in factory methods!
    That's because if you use them extensively, you have to update switches all over the place when you add another case!! Compared to polymorphic class/interface where you don't have to! :)
  8. Prefer exceptions to error codes! Happy path is much easier to read/understand.
    Codes poison your calling methods.. if(myFun() == OK).. all over the place. Unless you use a Monad or some wrapper with utility methods, but then you propagate that special type.. (Optional<T> for example) :D

Comments

Use them only when you really have to!

  1. Clarifications to unusual/specific/performace-related code is ok
  2. Warnings are ok..
  3. TODOs are ok (usually link the issue or something..)
  4. Javadocs are great!
  5. Don't comment out code, delete it!

Formatting

  1. Use company/project-wide settings and obey them! Commit it to git, or put into Jira somewhere.
  2. Use automatic formatter if possible, a Git hook or something.
  3. One blank line between functions/classes
  4. Declare variable near to its usage!
  5. Line length should be 80+, I prefer 120
  6. Put related functions near each other. I prefer to put private ones on the bottom

Objects

Procedural code makes it hard to add new data structures because all the functions must change.
OO code makes it hard to add new functions because all the classes must change. (Wadler's problem? typeclasses, visitors)

Also https://en.wikipedia.org/wiki/Law_of_Demeter (not that important IMHO)

Error handling

  1. Use exceptions! This is not C, you have a powerful mechanism at your hands.
  2. Use unchecked exceptions! Checked ones just clutter your method signatures and don't add much value to your code...
  3. Log the errors!!!
  4. Don't return null!!! Use null-object pattern, empty list/map, Optional<T> or throw exception..
  5. Don't pass null! Try to find another way, overload function etc.

Tests

Write clean and useful tests! Fast, independent, repeatable!

Systems

Use IOC principle! Instantiate/wire all needed classes in the main method!
Easier to understand, refactor and test. Use factories/DI if needed.