🎯 Chapter Insight
Naming is one of the most underestimated parts of software development.
We name variables, functions, classes, services, database columns, events, API endpoints, configuration values, and entire systems. Those names become the vocabulary developers use to understand and discuss the software.
A good name does more than identify something.
It communicates intent.
It tells the reader what a value represents, why a function exists, what responsibility a component owns, and how a concept fits into the larger domain.
A poor name does the opposite.
Names such as
data
,
item
,
manager
,
handler
, or
process()
may technically be valid, but they force the reader to investigate the implementation before understanding what the code actually means.
Every vague name creates a small tax on comprehension.
Pragmatic developers therefore treat naming as part of design. They choose names deliberately because they know that every future reader will depend on those names to reconstruct the original intent.
💡 Developer Lens
Consider a method called:
processData()
What does it process?
What kind of data?
What outcome should we expect?
Does it validate something, transform something, store something, or send something elsewhere?
The name tells us almost nothing.
Now imagine the same operation is called:
calculateInvoiceTotal()
The implementation may be identical in complexity, but the second name immediately gives the reader context.
That difference matters.
Developers spend far more time reading code than writing it. Every clear name reduces the amount of mental reconstruction required to understand what is happening.
This effect multiplies across a codebase.
A well-named system can often be understood by reading method names and relationships between components. A poorly named system requires repeatedly opening implementations, tracing values, and searching through call sites just to understand basic concepts.
Good naming reduces cognitive load.
Names Should Reveal the Domain
Some of the strongest names come from the language of the problem itself.
If the business talks about subscriptions, invoices, enrolments, shipments, approvals, or learning activities, the code should usually use those same concepts.
Generic technical names often hide useful domain knowledge.
For example, a class called:
DataManager
tells us very little.
But names such as:
SubscriptionRepository
InvoiceCalculator
EnrollmentPolicy
or
ShipmentScheduler
immediately communicate responsibility.
The goal is not to make names longer for the sake of being descriptive.
The goal is to make the concept visible.
When the language in the code matches the language used by domain experts, developers can reason about the system more effectively. Conversations with stakeholders become easier because everyone is discussing the same concepts.
Naming therefore becomes part of modelling the domain.
If you struggle to find a clear name for something, that may be telling you that the concept itself is not yet clear.
Vague Names Hide Responsibilities
Names often reveal design problems.
Imagine a class called
UserManager
.
What does it manage?
User creation?
Authentication?
Permissions?
Profiles?
Notifications?
Subscriptions?
If the answer is “all of them,” the naming problem may actually be a responsibility problem.
The same applies to methods such as:
handle()
execute()
process()
doStuff()
These names may be appropriate in certain abstractions where the surrounding interface provides context. But when they appear everywhere, they can hide what the software is actually doing.
A vague name sometimes exists because the code itself is vague.
Perhaps one function performs several unrelated operations. Perhaps a class has accumulated too many responsibilities. Perhaps the domain concept has never been properly identified.
Renaming can therefore become a design exercise.
When you try to give something a precise name and discover that no precise name fits, it may be time to reconsider what that piece of code actually represents.
Good Names Reduce the Need for Comments
Comments can be useful, but they often become necessary because the code does not communicate its intent clearly enough.
Consider:
// Check whether the user is allowed to edit the article
if ($u->p >= 3) {
// ...
}The comment explains something the code itself should probably express.
Imagine instead:
if ($user->canEdit($article)) {
// ...
}The intent is visible directly in the code.
This does not mean comments are bad. Comments are valuable when they explain decisions, constraints, unusual behaviour, or reasons that cannot be expressed through code alone.
But comments should not constantly translate vague code into understandable language.
If a comment merely explains what a poorly named variable or function means, improving the name may be the better solution.
Good naming turns code itself into documentation.
Names Should Evolve
One reason names become misleading is that software changes.
A function may originally perform one small task and later take on a broader responsibility. A class may begin with a temporary technical name before the domain concept becomes clear. A variable may continue using terminology that the business stopped using years ago.
The implementation evolves, but the name remains frozen.
Eventually, the name and the behaviour describe different things.
This is dangerous because developers naturally trust names.
If a method is called
validateOrder()
, a reader will assume that validation is its primary responsibility. If it also writes to the database and sends notifications, the name is now hiding significant behaviour.
Names should evolve alongside understanding.
Renaming is not cosmetic cleanup. It is a way to keep the mental model of the code aligned with reality.
When your understanding changes, your vocabulary should change with it.
Consistency Matters Too
A single clear name helps.
A consistent vocabulary helps even more.
Problems appear when the same concept has several names across the system.
Perhaps one part of the application uses
customer
, another uses
client
, and another uses
accountHolder
for the same entity.
Developers then have to determine whether these are different concepts or merely different labels.
The reverse problem can also occur.
One word may be reused for several unrelated concepts.
A generic word such as
status
might refer to payment status, workflow status, account status, or delivery status depending on the context.
Consistency reduces ambiguity.
When a domain concept has an established name, reuse it intentionally. Avoid creating unnecessary synonyms unless the concepts really are different.
A shared vocabulary makes both code and team communication more precise.
Short Is Not Always Better
Developers sometimes treat shorter names as cleaner names.
But brevity and clarity are not the same thing.
A variable named
x
may require only one character, but the reader has to remember what
x
represents.
A name such as
remainingRetryCount
is longer, yet immediately communicates meaning.
The right amount of detail depends on context.
A short loop variable inside three lines of code may be perfectly clear. The same abbreviation used across a large service may become confusing.
Good names give the reader enough information without adding unnecessary noise.
The objective is not maximum description.
It is minimum ambiguity.
Naming Is Communication
Code is not written only for machines.
Machines do not care whether a variable is called
x
,
result
, or
validatedCustomerAddress
.
Humans do.
The compiler needs syntax. Developers need meaning.
This is why naming deserves attention. A name is one of the most direct ways one developer communicates intent to another developer who may read the code months or years later.
Sometimes that future developer is you.
A few extra seconds spent choosing a precise name today can save minutes of investigation repeatedly in the future.
Across an entire codebase and an entire team, those savings become significant.
🧭 Reflection
Look through your current codebase and ask yourself:
Which names require an explanation before someone understands them?
Where do generic words such as
data
,
item
,
manager
,
helper
, or
process
appear without enough context?
Do your names reflect the language used by the business and domain experts?
Are there concepts that have evolved while their old names remained unchanged?
And perhaps most importantly:
If someone unfamiliar with the implementation read only the names, would they understand what the system is trying to do?
Names reveal how clearly we understand the software ourselves.
⚙️ Practical Tip
Find one vague name in your codebase this week.
Do not choose something complicated. Start with a variable, method, class, or service whose purpose is clearer than its current name suggests.
Ask:
- What concept does this actually represent?
- What responsibility does it have?
- What would I call it if I had to explain it to another developer?
- Does the domain already have a better term?
- Would the new name remove the need for a comment?
Then rename it.
Afterward, read the surrounding code again.
You may discover that one precise name makes an entire section easier to understand.
And if you cannot find a clear name, investigate why.
The difficulty may be revealing a deeper design problem worth solving.
Good names make intent visible.
And when intent is visible, software becomes easier to understand, discuss, review, and change.
🔢 #44 of 53 | The Pragmatic Programmer Series
This post is part of my 53-week series summarizing The Pragmatic Programmer, one timeless principle each week, translated into modern software practice and reflection.








