跪拜 Guibai
← All articles
Kotlin · Android

Boolean Variable Names Are Questions Your Code Asks — Make Them Readable

By RockByte ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Poor boolean naming is a direct tax on every code review, bug fix, and onboarding session. A single ambiguous `flag` can survive years in a codebase, silently forcing each reader to reverse-engineer intent from surrounding logic — and occasionally getting it wrong.

Summary

Boolean variables are not just labels; they are questions the code poses, and the value answers yes or no. When a name like `open`, `flag`, or `done` fails to form a coherent question, the answer becomes meaningless and bugs follow. Four prefixes cover most cases: `is` for state, `has` for possession, `can` for ability, and `should` for business-rule decisions. Mixing them — `isAccess` instead of `hasAccess`, or `hasActive` instead of `isActive` — forces readers to mentally re-parse the sentence, which is exactly where misunderstandings breed.

Negative names such as `isNotEnabled` or `isDisabled` create double negatives when combined with the `!` operator, adding cognitive load every time the condition is read. The fix is to default to positive forms and confine unavoidable negatives to system boundaries where they map external APIs. Method parameters present a separate trap: a call like `Execute(false, true, false)` erases all business meaning. Splitting methods, using enums, or introducing a configuration object keeps intent visible at the call site.

Common anti-patterns include throwaway names (`flag`, `check`), prefix mismatches, double negatives, overloaded booleans that secretly combine multiple conditions, and temporary flags recycled across logic stages. The discipline is straightforward: name a boolean so that six months later, the person fixing a bug — often yourself — can read the condition and know exactly what question is being asked.

Takeaways
Boolean names should read as a question the code asks; `flag`, `done`, and `check` fail that test completely.
Use `is` for state (`isActive`), `has` for possession (`hasAccess`), `can` for ability (`canEdit`), and `should` for business-rule decisions (`shouldRetry`).
Mixing prefixes creates grammatical nonsense: `isAccess` should be `hasAccess`, and `hasActive` should be `isActive`.
Negative names like `isNotEnabled` force readers to compute double negatives when combined with `!`; prefer positive forms.
When a negative name maps an external API (e.g., `noValidate`), confine it to the boundary and convert to a positive form internally.
Boolean method parameters create a trap: `Execute(false, true, false)` hides all meaning. Split methods, use enums, or pass a configuration object instead.
Overloaded booleans like `isValid` that secretly check multiple conditions should be replaced with explicit names such as `isReadyForBilling`.
Reusing the same local boolean across different logic stages turns it into a bucket of unrelated failures; early returns or a Result object are cleaner.
Conclusions

The framing of a boolean name as a question the code asks is a useful mental model that goes beyond style guides: if the name isn't a coherent question, the answer `true` or `false` carries no information.

The distinction between `can` and `should` is underappreciated in most codebases. Conflating ability with business-policy decisions is a common source of logic errors that survive review because the name looks plausible.

Refactoring tools can actively worsen boolean naming by mechanically inverting names (e.g., `isDisabled` to `isNotDisabled`), which suggests that naming conventions need to be enforced at review time, not left to automated transforms.

Concepts & terms
Boolean Trap
A method signature that accepts one or more boolean parameters whose meaning is invisible at the call site, e.g., `Execute(false, true, false)`. The fix is to split the method, use an enum, or pass a configuration object so each value's purpose is explicit.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗