Skip to content

32 · 32 · 5 min

When objects are the wrong answer

Every tool in this course has a cost, and a course that only lists benefits has not taught you to use them.

Over-engineering

java
interface Adder { int add(int a, int b); }
class DefaultAdder implements Adder {
    public int add(int a, int b) { return a + b; }
}
class AdderFactory {
    static Adder create() { return new DefaultAdder(); }
}

Three files, two indirections, and one plus sign. Nothing here will ever have a second implementation.

Abstraction buys the ability to change something later. If it will not change, you paid and got nothing.

The rule

Write the simple version. When you need a second case, then introduce the interface. Not before, because before, you are guessing what the second case will look like, and guesses about that are usually wrong.

Deep hierarchies

code
Animal -> Mammal -> Carnivore -> Feline -> BigCat -> Lion

Reading Lion now means reading six files to know what it does, and a change to Mammal can break Lion in a way nothing in Lion explains.

Two levels is usually enough. Beyond three, composition is almost always better.

Anaemic objects

java
class Order {
    private List<Item> items;
    public List<Item> getItems() { return items; }   // and 12 more getters
}

class OrderService {
    double total(Order o) { }      // all the logic lives out here
}

A class of nothing but getters and setters is a struct wearing a costume. The behaviour belongs with the data: order.total(), not service.total(order).