When should you introduce an interface?
Answer it out loud before you open anything. The value of the flags below is in comparing them to what you actually said — including whether you named a cost, or only a principle.
A service has fourteen classes and fourteen interfaces, each implemented exactly once, each named IThing for a class named Thing. A new engineer asks why, and the answer on the team is "so it is testable and loosely coupled". Meanwhile the one place with genuine variation — three payment providers — is a switch statement inside a 600-line class.
React to this
Say what you would change, what you would leave alone, and what you would need to know first.
You are shown:
```ts
interface IOrderRepository { save(o: Order): Promise<void>; findById(id: string): Promise<Order | null> }
class OrderRepository implements IOrderRepository { /* postgres */ }
interface IPriceCalculator { calculate(o: Order): Money }
class PriceCalculator implements IPriceCalculator { /* pure arithmetic, no I/O */ }
class PaymentService {
charge(o: Order, provider: string) {
if (provider === 'stripe') { /* 80 lines */ }
else if (provider === 'adyen') { /* 90 lines */ }
else if (provider === 'paypal') { /* 70 lines */ }
}
}
```
Which of these three should have an interface, which should not, and what would you do first?What it is really testing
Whether the candidate has a *criterion* rather than a habit. The interesting signal is that they can name the cost of an interface — indirection, a second place to change, a vocabulary the reader must hold — and therefore name the conditions under which it is worth paying. The scenario is deliberately inverted: the codebase has interfaces everywhere abstraction is not needed and none where it is.