Repository navigation
Clean Code
Good and consistent naming is important. It improves coherence and cohesiveness. Good naming is also hard, which in itself is good. To come up with a distinct and meaningful name you have to think about responsibilities. Many things need names...
Be suspicious of abbreviations. Industry standard abbreviations like UTC are fine. Company standard abbreviations are also usually OK. Defacto standard language / framework abbreviations like cb for callback are also OK, providing they will be understood by new developers. Any other abbreviations are likely to cause confusion, and increase cognitive load.
Be suspicious of class names ending in "er" and "or". A ResilientConnectionPool is a far more meaningful name than a ConnectionManager. A toExternalFormat method on the Job class will not break encapsulation, whereas a JobTransformer will have to interrogate the job for all of it private data.
When not mandated by the language, consistency is still a good thing. In languages like JavaScript where files can be required or imported, and assigned to variables it's clearer to keep the variable name and filename as consistent as possible. Repeating directory names within the filename (a.k.a stuttering), is an anti-pattern in languages which can be navigated via an IDE (e.g. Java), but may be the lesser of two evils where navigation is commonly filename based (e.g. JavaScript)
Adopting a hierarchical naming strategy (e.g. service-namespace-name) helps reduce conflicts, identifies service responsibilities and likely maintainers. The downside of a hierarchical naming strategy is that project names become tedious and long. Abbreviating risks compromising coherence. There's no right answer. Find a balance and be consistent with it.
Comments are usually meaningless to the person who didn't write them. Comments are usually meaningless to the person who did write them a few months later. Comments grow stale. Therefore...
- Write comments which explain complicated code. Instead write simple code and unit tests.
- Write comments to visually break up large functions. Instead write small functions.
- Write TODO or FIXME comments. Instead DO/FIX the code within a short enough timeframe that you won't forget.
- Write comments which explain complicated code that can't be simplified (e.g. because of a bug in a 3rd party library)
- Write comments that make people smile (but only occasionally).
Functions should be short - REALLY short. On average no more than a few lines. It's quite possible to write large applications with an average function body of under 4 lines. Functions should also operate at a single level of abstraction, e.g.
Instead of...
async function invite(user, organisation) {
if (user.preferences.contact ==== 'email') {
await emailService.sendInvitation(user, organisation)
} else if (user.preferences.contact === 'sms') {
await smsService.sendInvitation(user, organisation)
} else {
throw new Error('No preferred contact method');
}
}Consider...
async function getNotificationService(contact) {
if (contact === 'email') return emailService;
if (contact === 'sms') return smsService;
throw new Error('No preferred contact method');
}
async function invite(user, organisation) {
const notificationService = getNotificationService(user.preferences.contact);
await notificationService.sendInvitation(user, organisation);
}When it...
- Works
- Communicates
- Has no duplication
- Has no unnecessary bits