Cohesion, coupling, and public surface
A well-designed class does one job well (high cohesion) and exposes only what callers need (low coupling). In LLD, your first sketch should list public methods before fields — the API is the contract; implementation is negotiable.
| Concept | Good sign | Red flag |
|---|---|---|
| Cohesion | Methods share a single noun's lifecycle | UserManager + EmailSender + CsvExporter |
| Coupling | Depends on interfaces, not concrete types | new SmtpClient() inside domain logic |
| Encapsulation | Invariants enforced inside the class | Callers set balance directly |
| API size | 3–7 meaningful public methods | 20 getters/setters on a data bag |
Abstract class vs interface
Use an interface when multiple unrelated classes share a role (Payable, Cacheable) — especially when you need multiple inheritance of type. Use an abstract class when subtypes share substantial code and the is-a relationship is stable (AbstractList in the JDK). In interviews, default to interfaces for behavior contracts; reach for abstract classes only when you can name shared implementation.
Programming to interfaces
High-level code should read: void process(PaymentMethod method), not void process(CreditCard card). Factory or DI constructs the concrete type at the edge. This is DIP in code form and makes unit tests trivial (inject a fake).
Law of Demeter (practical form)
A method should only call: itself, its parameters, objects it creates, its direct fields. Avoid order.getCustomer().getAddress().getZip() — expose order.getShippingZip() instead. Reduces ripple effects when Customer internals change.
Senior-level signal
Proactively shrink APIs: "Callers don't need getInternalQueue() — they need submit(Job) and cancel(id)." Mention package-private helpers or private inner classes for implementation details. If the interviewer asks about immutability, note that value objects (Money, ISBN) should be immutable with validation in the constructor.
Where this goes next
Creational Patterns covers how objects enter the system — Factory, Builder, and why Singleton rarely belongs in a clean design.
Further Reading
Practice Tasks (Optional)
Design or implement locally in any language — no autograding. Focus on class structure, extensibility, and being able to explain trade-offs out loud.
- Sketch interfaces for a payment module15m
Without implementing: define PaymentMethod interface, two implementations (Card, Wallet), and a PaymentProcessor that depends on PaymentMethod — not concrete classes. 5–7 boxes on paper.