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
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
Animal -> Mammal -> Carnivore -> Feline -> BigCat -> LionReading 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
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).