Meaningful Names
- Use descriptive names for classes, functions, and variables.
- Avoid misleading or ambiguous names.
- Names should reveal intent and purpose.
Functions Should Do One Thing
- Each function should perform a single task.
- Avoid combining unrelated functionality into one function.
Small Functions
- Functions should be small and ideally 5-10 lines long.
- Break larger functions into smaller, more manageable ones.
Use Descriptive Function Names
- Function names should describe what they do.
- The name should explain the purpose of the function clearly.
Limit the Number of Arguments
- Functions should have as few arguments as possible (ideally zero or one).
- Use object arguments or structure to reduce argument count.
Avoid Side Effects
- Functions should not change the state of the system unexpectedly.
- Keep the function’s behavior predictable.
Don’t Repeat Yourself (DRY)
- Avoid code duplication. Extract common functionality into functions.
Prefer Exceptions over Error Codes
- Use exceptions for error handling rather than returning error codes.
- Don’t let error handling clutter business logic.
Handle Errors Gracefully
- Ensure error handling is clear and does not obscure code logic.
- Provide meaningful messages in exceptions.
Use Meaningful Contexts
- Ensure your code provides enough context to understand its purpose.
- Avoid relying on global variables.
Avoid Magic Numbers
- Replace magic numbers (e.g., 7 or 3.14) with named constants.
- This makes the code more readable and easier to modify.
Favor Composition Over Inheritance
- Use composition (has-a relationships) rather than inheritance (is-a relationships) where applicable.
- Inheritance should only be used when it makes sense semantically.
Follow the Principle of Least Astonishment
- Code should behave in a way that doesn’t surprise developers who read it.
- It should do what it seems to do.
Comment Only When Necessary
- Only comment when the code is not self-explanatory.
- Use comments to explain why something is done, not what it does.
Use Polymorphism Over If/Else or Switch Statements
- Replace long if-else or switch statements with polymorphism where applicable.
Keep Code Simple
- Avoid overcomplicating the design. Choose simplicity over cleverness.
Avoid Negative Conditionals
- Write conditionals positively (e.g., isLoggedIn instead of !isNotLoggedIn).
Classes Should Be Small
- A class should have one clear responsibility (Single Responsibility Principle).
- Avoid large, multi-purpose classes.
Cohesion
- Methods within a class should be closely related to the class’s purpose.
- Avoid methods that seem out of place in a class.
Open/Closed Principle
- Code should be open for extension but closed for modification.
- New functionality should not require modifying existing code.
Dependency Inversion Principle
- High-level modules should not depend on low-level modules. Both should depend on abstractions.
- Use interfaces to decouple the code.
Don’t Use Flags as Arguments
- Functions should not take boolean flags to control logic flow.
- Split logic into separate functions if necessary.
Encapsulation
- Keep data private. Expose only necessary information through methods.
- Avoid direct access to internal state.
Avoid Long Parameter Lists
- Functions with many parameters are harder to read and maintain.
- Prefer passing objects instead of multiple parameters.
Clean Up Resources
- Always ensure that resources (files, network connections, etc.) are properly released.
- Use try-with-resources or finally for cleanup.
Avoid Output in Functions
- Functions should not directly print to the console or produce output unless it is their sole purpose.
Test-Driven Development
- Write tests before writing code.
- Use tests to ensure that your code behaves as expected.
Keep Functions Pure
- Pure functions have no side effects and always return the same result for the same input.
Code Should Read Like Well-Written Prose
- Your code should be easy to read and understand, much like a narrative.
- Avoid convoluted or overly complex constructs.
Refactor Regularly
- Continuously improve your code through refactoring.
- Ensure that the code remains clean as you add new functionality.