Introduction
There is a famous quote when it comes to naming things in programming, which is attributed to Phil Karlton
"There are only two hard things in Computer Science: cache invalidation and naming things"
(Or the slight variation of "There are only two hard things in Computer Science: cache invalidation, naming things, and off by one errors")
But over the last few decades there are definitely a few common conventions. Using standard names for things frees up time to work on tougher problems than naming, and means future readers of your code can probably understand the concept better.
Why we spend time naming things correctly
If you see a variable called isActive
, you can probably assume it is a boolean. active
or ok
are not clear.
General rules to follow
Avoid Negative variable names:
Negative names can lead to double negatives, which are confusing.
- Bad 👎:
isWithoutAuth
- Good 👍:
isAuthenticated
Avoid abbreviations
Abbreviations can be ambiguous - not everyone will interpret it as the same meaning. Just use the full word, it is clearer.
(Although id
is probably an exception where it should always be used over identification
).
- Bad 👎:
calcAmt
- Good 👍:
calculateAmount
Pick a language and always use that
If you work in a modern company then it is likely you work with people originally from various countries around the world. It can be easy to end up with a codebase with a mix of words like color
and colour
.
I'd recommend just picking US spelling in your code (even if the app is localised only for a UK or AU audiece)
- Bad 👎:
productColour
- Good 👍:
productColor
Make booleans obvious by using is/has prefix
If you name something hasSubscription
, it is quite obvious that it is a boolean. Try to always do this, as something like subscription
could read as if it wasn't a boolean
-
Bad 👎:
active
-
Good 👍:
isActive
-
Bad 👎:
subscription
-
Bood:
hasSubscription
Avoid generic names
Words like value
, data
, item
are too generic. Try to avoid these terms
- Bad 👎:
item
- Good 👍:
product
Aim for consistency
Pick a convention for naming things, and use those everywhere.calculateAmount
- Bad 👎:
saveUserDetails
andfetchUserRow
- Good 👍:
saveUserDetails
andfetchUserDetails
Also pick a style for casing, and be sure you're consistent with it. Here are some examples (there might be other typical conventions for your library/language of choice)
PascalCase
for class namescamelCase
for most other variablesUPPER_CASE
for static constants
Common names for specific things
Transformers
If you're taking some data and transforming it to a different shape or different values then transformer
is a common and accurate name.
✅ copied// take a single CSV line, return object with id/name/amount function csvLineTransformer(csvLineInput: string) { const fieldValues = csvLineInput.split(',') return { id: fieldValues[0], name: fieldValues[1], amount: fieldValues[2] } }
Validator
If you need to check if data is valid/correct, then its almost always called a validator.
// throw error if validation issue function validateUser(formData) { if(!formData.username) throw new Error('Validation missing username') if(formData.username.length > 25) throw new Error('Validation username is too long') }
Schema
Used when describing the shape of some data structure. Often used with database designs.
class UserSchema { public username: string; public password: string; }
Parser
When you need to take some data (e.g. some string) and understand its own data structure. They are quite different things, parsers and transformers can sometimes be very related
✅ copiedfunction parseURL(url) { const regex = /^(?:(\w+):\/\/)?([^\/:]+)?(?::(\d+))?([\/\w.-]*)?$/; const matches = url.match(regex); return { protocol: matches[1], hostname: matches[2], port: matches[3], pathname: matches[4] }; }
Middleware
For code that runs 'between' different parts of your application. A typical use for middleware is in HTTP servers the incoming HTTP request can go through multiple middlewares to either transform the incoming data (before passing to next one or final endpoint handler function) or to do something with that data
function loggerMiddleware(req, res, next) { console.log(`Incoming request for ${req.url}`); next(); // Process the next middleware })
Adaptor
When you have some functionality with a specific interface, and you need to convert it to another interface/shape.
It is also known as a 'wrapper' (or a bridge, although that is technically a slightly different thing)
Normalizer
When you need to make data uniform in scale, format, or structure
function normalizeEmail(email: string): string { return email.toLowercase().trim() }