You can feel a good name settle in your hands. It lands with a small click, like a drawer closing. The code around it quiets. The document with it reads cleaner. A teammate you have never met can guess what it holds and how to use it without the ritual of a tour. Bad names, on the other hand, are a wind. They blow meaning from one corner to another until no one can find it. The longest arguments in software do not begin as arguments. They begin as a name that did not fit and a team too busy to admit it.
Naming is not a stunt. It is applied anthropology. You are listening for the word the group would reach for in a hallway when no one is looking. Start with the shape of the thing and the action it makes possible. A function that changes a state should say what it changes and into what. A table that records facts should choose a noun that would not blush in the company of accountants. A service that mediates between two places should say the places, not the theory. Theory ages; places stay.
Avoid placeholder nouns that feel like fog. Manager, handler, thing, data. These words are the linguistic equivalent of a shrug. They tell a future reader that you did not know yet. There is no shame in not knowing. There is cost in pretending you do. Leave a name as a question mark during a spike. When you commit, commit to a word with a spine. “InvoiceTotals” is better than “FinanceData.” “GrantAccess” says more than “Process.” “RetryEnvelope” tells a colleague that someone thought about the rules of the road.
Good names align with boundaries. If you have a bounded context that speaks in euros and net terms, do not let a variable inside it whisper about dollars and coupons. Fold the vocabulary of the context into the code. Do not import jargon from another layer because it sounds clever. Cleverness sours. Local correctness endures.
The best names are discoverable. They are the names a teammate would try when they guess at an API. You can test this. Ask someone to write the call they wish existed. If their guess is three keystrokes away from the truth, you have a good name. If their guess is a sentence and yours is a paragraph, you have a refactor waiting for you like a bill.
Length is not the enemy. Ambiguity is. Short words that mislead cost more than long words that guide. That said, remove filler. Words like “Helper,” “Utils,” and “Common” belong only at the edges, and even then, they prefer retirement. Replace pairs like “CreateNewRecord” with “Create.” When you can swap an adjective for a noun that carries the property within it, do so. “EncryptedPayload” beats “PayloadWithEncryption.” A sentence wants to be read; a name wants to be scanned.
Names earn their keep when they hold steady under change. This is the hardest test. A name that fits today and tomorrow is anchored in what the thing is, not how it works this week. Implementation details churn. Intent, when it is real, lasts. If you feel a name eroding as you write the body beneath it, stop and listen. Either the name is wrong or the body is doing too much. In both cases, the cure is separation.
Teams can make naming a shared craft with two small habits. Keep a short dictionary in the repo, the kind you would tape to a monitor: ten to twenty words that this codebase uses in a specific way. Add to it as you discover collisions. Second, during reviews, comment on names before you comment on loops. A loop works or it does not; a name either helps the next person or leaves them to wander. The loop will be rewritten three times this year. The name might outlive you.
You will still get names wrong. Everyone does. The mercy is to change them early and with care. Write a small commit that does nothing but rename and pass tests. Explain the reason with a single paragraph. Your teammates will thank you with their next hour, the one they do not have to spend paging through history to learn what “Item2” meant in the spring of a year no one misses. When the name is right, it is like that drawer again. A click, a stillness, a place where your hands remember what belongs.