Design to Contracts
intermediate14 min readLesson 67 of 180
Programming to interfaces with constructor injection: the one-line DIP, and why small promises beat fat ones.
Design to contracts
An interface is a promise callers can rely on and implementations can swap. The intermediate skill is choosing what belongs in the promise:
public interface PaymentGateway {
PaymentResult charge(Money amount, Card card);
}
High-level code (checkout) should depend on PaymentGateway, not on
StripeGateway. That is the Dependency Inversion Principle in one line:
details depend on abstractions, never the reverse.
public final class CheckoutService {
private final PaymentGateway gateway;
public CheckoutService(PaymentGateway gateway) { // injected
this.gateway = gateway;
}
public PaymentResult checkout(Order order) {
return gateway.charge(order.total(), order.card());
}
}
Why this pays off:
- tests swap in a fake gateway — no network, no secrets
- adding PayPal means writing a new class, not editing checkout
- the interface documents the only methods checkout actually needs (interface segregation: small promises beat fat ones)