Clean code should be readable.
Clean code should be maintainable.
Naming #
Names should be meaningful.
Names should be distinctive.
Names should be consistent.
Names should not include redundant information, disinformation, slang, or unclear abbreviations.
Use nouns or short phrases with adjectives for variables and constants.user isValid
Use verbs or short phrases with adjectives for functions and methods.saveUser auth.isValid
Use nouns or short phrases with nouns for classes.User
snake_case
- Python Variables, Functions
camelCase
- JavaScript Variables, Functions
- Java Variables, Functions
PascalCase
- Python Classes
- JavaScript Classes
- Java Classes
kebab-case
- HTML Element Attributes
- CSS Variables
Formatting #
Vertical #
Multiple concepts should be split into multiple files.
Different concepts should be separated by spacing.
Similar concepts should be together without spacing.
Related concepts should be kept close together.
Horizontal #
Indentation
Horizontally long statements should be broken into multiple shorter ones.
Comments #
Legal Information
Warnings
To-Do Notes
Explanations which cannot be replaced by good naming are good comments.
Objects and Classes #
Classes should have a single responsibility.
Classes should be open for extension but closed for modification.
Classes should be highly cohesive. Cohesion describes the extent to which methods rely on properties. Maximum cohesion is that every method uses every property. Minimum cohesion is that methods do not use any properties.
Law of Demeter: Tell! Don't Ask!
Functions #
Don't Repeat Yourself (DRY)
Multiple parameters can be minimized into one. You don't have to concern the order of parameters.
class User1 {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
interface UserData {
name: string;
age: number;
}
class User2 {
name: string;
age: number;
constructor(userData: UserData) {
this.name = userData.name;
this.age = userData.age;
}
}
const user1 = new User1("John", 20);
const user2 = new User2({ age: 20, name: "John" });
A big function should be split into small functions that do one thing. The name of a function implies its level of abstraction. In a big function, small functions should have the same level of abstraction.
In a function, when something affects outside of the function, it is called a side effect. When a function has a side effect, the name of the function should imply that the side effect will occur.saveUser showErrorMessage
A pure function always yields the same output with the same input and has no side effects.
Function names should be positive.isEmpty isValid
Unit testing helps functions to be clean.
Control Structures #
Avoid deep nesting by using error guards to fail fast, factory functions, and polymorphism.