skip to content

What naming conventions distinguish classes, methods, and boolean-returning members, and why does following them consistently matter?

level: juniorimportance: must knowfreq 65%

answer

  1. class = noun, method = verb, boolean = predicate
  2. isEmpty / hasChildren / canRetry
  3. no negated booleans → double negatives
  4. get* must be cheap and side-effect-free
  5. factory names say which construction: ofSeconds, fromJson

basics

~20 s

Classes and modules get noun phrases (things): Invoice, PaymentGateway. Methods get verb phrases (actions): send, calculateTotal. Boolean members read as a true/false statement: isEmpty, hasPermission. Readers then parse code as sentences instead of decoding it.

solid answer

~40 s

Conventions: **classes/types/modules = noun phrases** (`Customer`, `OrderRepository`) — never verbs, and never vague suffixes like `Manager`, `Processor`, `Data`, `Info`. **Methods/functions = verb phrases** (`deleteAccount`, `calculateTax`); accessors and mutators follow the platform convention (`getX`/`setX`, or `x()`/`withX()`). **Booleans = predicates** that read as an assertion: `isActive`, `hasChildren`, `canRetry`, `shouldRetry`. Avoid negated booleans (`isNotReady`) because call sites become double negatives. Factories and converters get intent-revealing static names: `fromJson`, `parse`, `of`, `valueOf`. The payoff is that call sites read as sentences — `if (cart.isEmpty()) order.reject()` — so scanning code becomes reading rather than decoding. Consistency matters more than which convention you pick: a mixed vocabulary forces readers to check every implementation, and it defeats IDE and grep-based discovery.

code

pseudocode · 11 lines
pseudocode
class DiscountCalculator {        // noun phrase: a thing with one job
    calculate(order) -> Money     // verb phrase: an action
}

if (cart.isEmpty()) ...           // predicate: reads as an assertion
if (user.hasRole(ADMIN)) ...
if (!job.canRetry()) ...          // negate at the call site, not in the name

// avoid:
if (!job.isNotRetryable()) ...    // double negative
report.render(true)               // what does `true` mean here?

go deeper

for a junior

State the three rules — classes are nouns, methods are verbs, booleans read as assertions — with one example each.

for a middle

Add the sub-rules: no negated booleans, get* must be cheap and side-effect-free, named factory methods, units in names, plural for collections.

for a senior

Connect naming to command–query separation and API discoverability; note that vague suffixes like Manager usually signal a responsibility problem, and that boolean parameters should become enums.

for a principal

Argue that the choice of convention matters less than uniform enforcement; push conventions into linters and style guides, and treat predictable naming as a discoverability property of the codebase, not a matter of taste.

## The grammar of code Most mainstream languages are built so that well-named code reads like English sentences: subject (object/variable), verb (method), object (arguments). Naming conventions exist to keep that grammar intact. ### Classes, types, modules → noun phrases A class models a *thing* or a *role*: `Customer`, `Invoice`, `HttpConnection`, `PaymentGateway`, `OrderRepository`. Guidelines: - Prefer concrete domain nouns over generic ones. `Manager`, `Processor`, `Handler`, `Data`, `Info`, `Helper`, `Util`, `Service` are *weasel suffixes*: they say "this does something with X" without saying what. They are not banned — `OrderService` is a fine layering convention in many codebases — but if you cannot describe the class without them, that is usually a sign the class has no single responsibility. - Role-suffix nouns derived from verbs are legitimate and often the clearest option for a single-purpose object: `DiscountCalculator`, `PriceFormatter`, `RetryPolicy`. - Avoid verb-phrase class names (`ApplyDiscount`) *unless* your codebase deliberately uses the Command pattern, where a class represents a request to do something; then name it as a command noun (`ApplyDiscountCommand`) so the convention is explicit. ### Methods and functions → verb phrases A method is an *action*: `save`, `deleteAccount`, `calculateTotal`, `renderPage`. Sub-rules: - **Accessors/mutators** follow the platform convention: `getName`/`setName` in Java-style codebases, `name()`/`withName()` in others. Pick the one your language community uses; do not mix both. - **A `get`-prefixed method should be cheap and side-effect-free.** If `getConnection()` actually opens a socket, the name lies; `openConnection()` or `createConnection()` tells the truth. This is the *command–query separation* idea: a method should either return information (query, no observable side effects) or change state (command, ideally returning nothing). - **Static factory methods** get intent-revealing names — `Duration.ofSeconds`, `Money.fromCents`, `Instant.parse` — which is one of the main advantages of factories over constructors: a constructor can only be named after its class, a factory can say *which* construction it performs. ### Booleans → predicates A boolean member should complete the sentence "it is true that …": - `isEmpty`, `isActive`, `hasPermission`, `canRetry`, `shouldRetry`, `wasModified`. - **Avoid negation in the name.** `isNotReady` produces `if (!thing.isNotReady())` at call sites — a double negative readers routinely misparse. Name the positive and negate at the point of use. - **Avoid `check…`/`validate…` for something that returns a boolean and does nothing else.** `checkEmpty()` does not say what `true` means. `isEmpty()` does. Reserve `validate…` for methods that throw or return a result object. - **Avoid ambiguous flags as parameters.** `render(true)` is unreadable at the call site; prefer an enum (`render(Mode.PREVIEW)`) or two named methods (`renderPreview()`, `renderFinal()`). ### Collections, counts, units - Plural for collections (`orders`), singular for the element (`order`). Do not name a collection after the wrong container type (`accountList` when it is a set). - Put units in the name when they are not obvious: `timeoutMillis`, `weightKg`, `priceInCents`. Unit confusion is a classic and expensive class of bug. ### Interfaces and implementations Naming conventions here vary by ecosystem and are legitimately contested: - Some communities prefix interfaces with `I` (`IShape`) — common in the C#/COM lineage, discouraged in Java/Kotlin style guides as type encoding. - Others name the interface after the abstraction (`Shape`) and give the implementation a qualifier describing *how* it implements it (`CircleShape`, `JdbcOrderRepository`, `InMemoryCache`). Avoid the placeholder `ShapeImpl`, which says nothing about which implementation it is — it is only tolerable when there is genuinely exactly one and no distinguishing quality. ## Why consistency beats cleverness When a codebase is consistent, three things become possible: 1. **Reading without decoding.** `if (cart.isEmpty()) order.reject()` is parsed once, not analysed. 2. **Prediction.** A developer can *guess* the name of a method they have not seen (`user.hasRole(...)`) and be right. This is discoverability, and it is worth real money in a large codebase. 3. **Tooling.** Grep, IDE completion, code generation, and lint rules all key off predictable prefixes. Mixed vocabulary (`fetchUser`, `getUser`, `retrieveUser` for the same operation) defeats all three and forces readers to open every implementation to confirm they do the same thing. Whichever convention a team picks matters far less than that it is applied uniformly and, ideally, enforced by a linter or style guide rather than by review nagging.

  • Why is `isNotReady()` a poor boolean name?
    Because call sites need the opposite case too, producing `!isNotReady()` — a double negative that readers frequently misread. Name the positive condition (`isReady`) and let the call site negate it once, visibly.
  • Is `OrderManager` an acceptable class name?
    It is legal but weak: `Manager` says "does something with orders" without saying what. If you cannot replace it with a specific noun, the class probably has several responsibilities and should be split into named collaborators such as `OrderValidator`, `OrderPricer`, `OrderRepository`.
  • What is wrong with a `getX()` method that opens a network connection?
    The name promises a cheap accessor, so callers will happily invoke it in loops, in logging, or in a debugger watch expression. Name it for what it does — `openConnection()` or `connect()` — so the cost and the side effect are visible.

Code is a sentence: objects are the nouns, methods are the verbs, booleans are the yes/no questions. Break the grammar and every reader has to re-parse the sentence from scratch.

saying these in an interview costs you the question

  • Naming boolean methods `checkX()` or `validateX()` when they merely return a flag.
  • Negated boolean names such as `isDisabled`/`isNotValid` used in both polarities.
  • Verb-phrase class names outside an explicit Command-pattern convention.
  • Reaching for `Manager`, `Helper`, `Util`, `Data`, `Info` as the default class suffix.
  • Boolean parameters at call sites (`render(true)`) instead of enums or two named methods.
  • Insisting one convention (e.g. the `I` interface prefix) is universally correct rather than ecosystem-specific.

context