RizTech Academy logo
RizTech Academy
Best Practices: Code Others Can ReadLesson 1 of 540 min

Naming things, which is most of the job

There is an old joke that the two hard problems in computer science are cache invalidation, naming things, and off-by-one errors. The joke is about the third one. The serious part is the second.

You will spend far more time reading code than writing it — your own included, six months later, with no memory of writing it. Names are the interface between what the code does and what the next person believes it does, and when those two drift apart, that is where bugs live.

A name should say what, not how

// how
List<Delivery> filterListByDateRangeUsingStream(List<Delivery> list, YearMonth m)

// what
List<Delivery> deliveriesIn(YearMonth month)

The second survives changing the implementation. The first is a comment about the current implementation, written where a comment cannot be ignored, and it becomes a lie the moment somebody rewrites the body.

Length should match scope

A short name is fine when its whole life is visible:

for (Delivery d : deliveries) {
    total += d.tiffins();
}

d is perfectly readable — it is born and dies within two lines. But a field living for the lifetime of an object, read from twenty places, needs to carry its meaning with it:

private final Map<String, Subscriber> subscribers;   // good
private final Map<String, Subscriber> m;             // not

The further a name travels, the more it has to carry. A loop variable, three characters. A private field, a word. A public API method, as many words as it takes.

Say what the units are

This is the single highest-value naming habit in this course, and the capstone is built on it:

long pricePaise
long amountPaise
int tiffinsPerDay
Duration timeout

price alone raises a question the reader has to answer from somewhere else: rupees or paise? pricePaise cannot be misread, and the day somebody writes pricePaise = 285 instead of 28_500, the name is standing right there arguing with them.

The same goes for time (timeoutMillis, retryAfterSeconds), size (maxSizeBytes) and anything with a scale. A name carrying its unit is a bug that cannot be written.

Booleans read as questions

if (subscriber.isPaused()) { … }
if (order.hasDeliveryAddress()) { … }
if (delivery.canBeCancelled()) { … }

is, has, can, should. The test is whether if (name) reads as English. if (subscriber.paused()) is fine; if (subscriber.pause()) reads as a command and will be misread as one.

And avoid negatives:

if (!subscriber.isNotActive())   // two negatives, one confused reader
if (subscriber.isActive())       // same thing

Say no to the noise words

Some words add characters and no meaning:

DeliveryData      // as opposed to a Delivery that is not data?
DeliveryInfo
DeliveryObject
processDelivery   // "process" means nothing
handleDelivery
doRecordDelivery
manageDeliveries

Manager, Helper, Util, Processor, Handler, Data, Info, Object. If removing the word does not change the meaning, remove it.

The exception is a genuine convention: DeliveryStore says where deliveries live, and BillingService says this does billing work and holds no data of its own. Those carry meaning. DeliveryHelper does not.

A class you cannot name is usually a class doing more than one thing. That is a design problem showing up as a naming problem, and it is worth listening to.

Be consistent about one idea

Pick one word per concept and use it everywhere:

// Pick one:
getDelivery / fetchDelivery / retrieveDelivery / loadDelivery

// and one:
customer / client / subscriber / user

The capstone says customer in Delivery and Subscriber for somebody with a plan — and those are genuinely different things, which is exactly when two words are right. Two words for the same thing makes a reader search for a distinction that is not there.

The JDK is consistent and you can lean on it: size() for collections, length() for strings, length for arrays. That inconsistency is a historical accident everybody has had to memorise — a good example of the cost.

Java's conventions are not optional

Thing Convention Example
Class, interface, record, enum UpperCamelCase, a noun BillingService
Method lowerCamelCase, usually a verb billPaise
Variable, field lowerCamelCase, a noun tiffinsPerDay
Constant UPPER_SNAKE_CASE MAX_TIFFINS_PER_DAY
Enum constant UPPER_SNAKE_CASE Plan.STUDENT
Package all lowercase, no underscores com.riztech.tiffin
Type parameter one capital letter T, K, V, R
Test method whatever reads as a sentence rejectsAPincodeStartingWithZero

These are not matters of taste in Java the way they are in some languages. Every codebase you join will follow them, every tool assumes them, and departing from them just marks the code as written by somebody who did not know.

Interfaces are not prefixed with I. That is a C# habit. In Java the interface gets the good name — List — and implementations are specific: ArrayList, LinkedList.

Test names are documentation

@Test void test1()                              // useless
@Test void testPincode()                        // what about it?
@Test void rejectsAPincodeStartingWithZero()    // now the failure report reads

When a build fails at 9pm, the test name is the first and often only thing you see. Write it so that reading it tells you what broke.

Names as a design signal

Naming difficulty is information. Listen to it.

  • "I cannot name this method" — it probably does two things. Split it and the names appear.
  • "I need and in the name" — saveAndNotify is two methods.
  • "I keep writing Manager" — the responsibility is not clear yet.
  • "The name is very long" — either the method is doing too much, or its context is missing and it belongs on a different class.
// hard to name
void processDeliveryAndUpdateInvoiceAndNotify(Delivery d)

// easy to name
void record(Delivery d)
void updateInvoice(Delivery d)
void notifyCustomer(Delivery d)

Check your work

Why names matter more than they look: you read far more code than you write, and a name is what the next person believes the code does.

Why to name what, not how: a name describing the implementation becomes a lie when the implementation changes.

How length relates to scope: the further a name travels, the more it must carry — three characters in a two-line loop, a full phrase in a public API.

The highest-value habit here: put the unit in the name — pricePaise, timeoutMillis. A name carrying its unit is a bug that cannot be written.

How booleans should read: as a question, with is, has, can or should, and never as a double negative.

Which words to delete: Manager, Helper, Util, Data, Info, process, handle — if removing it changes nothing, remove it.

Why two words for one idea is worse than a bad word: the reader searches for a distinction that does not exist.

Why Java's conventions are not taste: every codebase and every tool assumes them.

Why interfaces have no I prefix: the interface gets the good name and implementations are specific.

What naming difficulty tells you: a method you cannot name is doing two things, and and in a name is a split waiting to happen.

Practice

  1. Open your capstone and find the three worst-named things in it. Rename them and see whether anything reads better.
  2. Find every variable holding money in your code. Confirm each has Paise in its name; fix the ones that do not.
  3. Find a boolean method that does not start with is, has, can or should. Read a call site aloud.
  4. Search your code for Manager, Helper, Util, Data, Info. For each, try deleting the word.
  5. Find two words used for the same concept in one codebase. Pick one and change the other.
  6. Look at your test names. Rewrite three so the failure report alone tells you what broke.
  7. Find a method whose name contains and. Split it.
  8. Rename a loop variable from d to delivery. Decide whether it improved.
  9. Ask somebody to guess what one of your methods does from its name alone.
  10. Find a method you struggled to name. Work out what it was telling you.

Next: how big is too big.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship