intermediate
Interfaces and contracts
Define the behavior a client needs, keep contracts small, and let implementations vary without leaking concrete dependencies.
An interface defines a behavioral contract—operations, preconditions, postconditions, and error semantics—without dictating implementation. Small, role-specific interfaces (ISP) let clients depend only on `Readable` or `Writable` rather than a kitchen-sink `Storage`.
Contracts enable testing with fakes and swapping infrastructure without rewriting domain logic.
On interviews: split a fat interface into two role-based ones and explain impact on mocks and production adapters.
Common pitfalls: interfaces that leak DTO shapes from one layer, boolean flag methods instead of separate types, and contracts so large every mock is painful.
The trade-off is more types to manage versus clearer boundaries and safer refactors.
Checklist:
- Size interfaces to client roles.
- Document failure modes in the contract.
- Implement domain against interfaces, not vendors.