🏛️ Design Principles & Patterns · Advanced

Clean code in Java

Naming, small methods, avoiding nulls, meaningful exceptions.

🧩 The mysterySaving an order fails, nobody gets an error, and the data is just... gone. The bug is a comment that says "ignore".

Names that reveal intent

Good names make comments unnecessary. d needs a comment; elapsedDays doesn't. Booleans read like questions (isEligibleForRefund), collections are plural (customerEmails). Names like data2 say nothing about what they hold or why the 2 exists.

int d; // elapsed time in days
int elapsedDays;
boolean isEligibleForRefund;
List<String> customerEmails;

Small methods, one level

A good method does one thing at one level of abstraction, so it reads like a story. Details live in the small methods it calls, each easy to name, test and review.

void checkout(Cart cart) {
    validate(cart);
    charge(cart);
    sendReceipt(cart);
}

Saying "nothing"

✗ Returns null
List<Order> ordersOf(User u) {
    if (u.isNew()) return null;
    ...
}

Every caller needs a null check; one forgotten check is a NullPointerException.

✓ Returns empty
List<Order> ordersOf(User u) {
    if (u.isNew()) return List.of();
    ...
}
Optional<User> findByEmail(String e);

An empty list already means "nothing found" and is safe to loop over. For a single value, use Optional.

🔮 Predict it

Optional in action

What does this print?

Optional<String> city = Optional.of("rome");
Optional<String> none = Optional.empty();
String a = city.map(String::toUpperCase)
    .orElse("unknown");
String b = none.map(String::toUpperCase)
    .orElse("unknown");
System.out.println(a + " " + b);
  1. ROME unknown
  2. ROME null
  3. rome unknown
  4. Throws NoSuchElementException
Show the answer

map transforms a present value, so city becomes "ROME". On an empty Optional, map does nothing and orElse supplies the default. No null checks, and the type forces callers to handle "no value".

⚠️ The trap

Swallowed exceptions

An empty catch block turns a failure into silence. The save fails, the caller thinks it worked, and nobody finds out until data is missing. Log it and rethrow, or wrap it in a meaningful exception.

void save(Order o) {
    try {
        repo.write(o);
    } catch (IOException e) {
        // ignore
    }
}

Meaningful exceptions

Throw a specific type with a message that includes the bad value. RuntimeException("error") says nothing. Magic return values like -1 and printed errors are easy to ignore. IllegalArgumentException with details tells the caller exactly what went wrong.

if (amount < 0) {
    throw new IllegalArgumentException(
        "amount must be >= 0, was " + amount);
}
💼 In the real world

Code that survives review

Code is read far more often than it's written. Reviewers flag cryptic names, 200-line methods, return null for collections and empty catch blocks constantly. Clean code shortens debugging at 3 a.m. because the logs and exceptions tell you what broke.

Key takeaways

  1. Names reveal intent: elapsedDays, not d
  2. Small methods at one level of abstraction
  3. Return empty collections or Optional instead of null
  4. Throw specific exceptions with useful messages; never swallow them

💡 Good code is like a good street sign: you understand it at a glance, without stopping the car.

🤯 Did you know?

Tony Hoare invented the null reference in 1965 for the ALGOL W language. In a 2009 talk he called it his "billion-dollar mistake".

Practice questions

What does this print?

Optional<String> nick = Optional.empty();
String shown = nick.map(String::toUpperCase)
    .orElse("guest");
System.out.println(shown);
  1. GUEST
  2. null
  3. Throws NoSuchElementException
  4. guest
Check your answer

guest. map() on an empty Optional does nothing, so orElse supplies the default. No null checks needed.

Three of these names reveal intent. Which is the odd one out?

  1. elapsedDays
  2. isEligibleForRefund
  3. customerEmails
  4. data2
Check your answer

data2. data2 says nothing about what it holds or why the 2 exists. Good names make comments unnecessary.

New world: Data Structures & Algorithms. How can about 20 comparisons find one item among a million?