Clean Code (Uncle Bob) - robbiehume/CS-Notes GitHub Wiki
Clean code tips
- Name variables/properties in a way that there is no room for confusion/ambiguity
- Break complicated pieces of logic into descriptive variables so it reads more like english. Especially for complicated conditional expressions in an if statement
- Your code should speak for itself without comments whenever possible
Uncle Bob Clean Code Videos
Lesson 1
- Almost everything in the world relies on software
- Your code will start out messy, but you need to clean it up after you get it to work
- "The only way to go fast is to do it well"
- Your job is to write code that other people can easily understand and maintain
- Every line of a function should be at the same level of abstraction, and that level should be one below the name
- Functions should be no more than 10-20 lines long
- It's best to abstract lots of lines in a function into multiple function calls. E.g., in one higher level function, there could be calls to many other lower level functions
- Constantly ask yourself where you could abstract multiple lines into a single function call
- Many IDEs have an extract button to help with this
- If possible, a function should do only one thing
- The key to maintaining many small functions is to name them well
- Most large functions can really just be represented as a class with variables and many little functions in it
- If you are passing more than 3-4 arguments to a function, ask yourself if you can use an object or other strategy instead
- You should almost never pass a boolean to function because that likely means there's an if statement with 2+ condition branches that could just be split into two separate functions
- Use polymorphism instead of large switch statements
- Open/Close principle: a module should be open for extension but closed for modification. I.e., you should be able to extend the behavior of a module without modifying that module
- Try to prevent side-effects, which is a change to the state of the system. E.g. if you call a function and that function causes the system to change state, then that function had a side-effect (open() and close(), malloc() and free(), etc.)
- A function that returns a value, shouldn't change the state of the system. If it's a void function, it should change the state
- Use good exceptions; no nested try blocks
- DRY: Don't Repeat Yourself
- Write good unit tests for individual components of your code, not just the system as a whole
Lesson 2:
- The purpose of a comment is to explain the purpose of the code, if the code can't explain its own purpose
- Not all comments are good/helpful though, make sure you write them well
- The proper use of comments is to compensate for our failure to express ourselves in code. Therefore every use of a comment represents a failure^, so don't comment first. Try everything else, then comment as a last resort
- Too many comments can get in the way of the code
- If comments aren't maintained over time with the code, then the comments can end up describing something that is no longer true
- Explain yourself in code not comments
- Add a comment for any regular expressions
- Commented out code is the worst. It's okay to do it while experimenting and testing logic, but never leave it
- Don't add comments about code that's somewhere else. If you write a comment, only talk about the code that's right there. Because if you comment about other code in other places, that code could change and your comment may no longer be true
- The names of variables should describe the significance of what the variable contains
- General rule of thumb to try to follow: the length of the variable name should be somewhat proportional to the size of the scope that contains it
- Class attributes should be pretty long/descriptive
- For functions, the bigger the scope of the function, the smaller the name of the function should be and vise versa
- For classes, it should also be like functions where the size of the name is inversely proportional to the size of its scope
- A good system of names (variables, functions, classes, etc.) tells you not just about the single function you're looking at, but also the entire context of the system
Lesson 3:
- Only release code when you know to the best of your ability that it works
- Learn how to write good unit tests
- Automate your tests
Lesson 4:
TDD Demo: https://youtu.be/58jGpV2Cg50?t=2640
- 3 rules of Test Driven Development (TDD):
- You are not allowed to write any production code until you have first written a test (which fails at first)
- You are not allowed to write more of a test than is sufficient to fail
- You are not allowed to write anymore production code than is sufficient to pass the current failing test
- Write unit tests before coding
- Design your code to be testable
- It's actually very rewarding to have tests first because as your code progresses you get to keep checking off passed tests
- Write the test that forces you to write the code you already know you want to write
- Throughout the TDD process, you should be making the tests more constrictive and the code more general
- As you build tests, start from the bottom up. I.e. the tests should start easier/mundane and get harder/higher-level