Interfaces
An interface describes what a caller may request without choosing the concrete implementation. Method names, inputs, outputs, and failure behavior all belong to the contract.
What you’ll understand
- An interface describes what a caller may request without choosing the concrete implementation. Method names, inputs, outputs, and failure behavior all belong to the contract.
- Both senders implement send(message), and the caller receives a sender through its constructor.
- Evaluate the tradeoff: Contracts help substitution only when semantics agree. JavaScript uses duck typing here; Python uses a small abstract base class. Neither style excuses incompatible error behavior.
Useful first: Classes and Objects
The idea and when to recognize it
An interface describes what a caller may request without choosing the concrete implementation. Method names, inputs, outputs, and failure behavior all belong to the contract.
- Requirement: A receipt service needs to send a message through email or SMS and should not depend on either provider’s construction details.
- Change to anticipate: Swap the delivery implementation without rewriting the receipt caller.
- Design goal: Both senders implement send(message), and the caller receives a sender through its constructor.
Start with the concrete problem
A receipt service needs to send a message through email or SMS and should not depend on either provider’s construction details.
Swap the delivery implementation without rewriting the receipt caller.
| Direct implementation | Revised design |
|---|---|
| Branching on a provider name inside the caller couples business logic to concrete delivery types. | Both senders implement send(message), and the caller receives a sender through its constructor. |
| The baseline case can hide the problem. Compare the extension and boundary fixtures before accepting this design. | Contracts help substitution only when semantics agree. JavaScript uses duck typing here; Python uses a small abstract base class. Neither style excuses incompatible error behavior. |
Responsibilities and contracts
Both senders implement send(message), and the caller receives a sender through its constructor.
- ReceiptService: Depends on the sender contract. Public operations: send(message)
- Sender: Defines message delivery. Public operations: send(message)
- EmailSender: Implements the same contract. Public operations: send(message)
Read the design
Select a participant to inspect its responsibility and public operations. Follow the labeled relationships; an arrow indicates direction, while the legend distinguishes ownership, substitution, and temporary use.
Preparing the design walkthrough…
Follow the interaction
Choose a supplied workload and compare the direct and revised implementations. Step through the same operation in both languages. Object values are recorded after each highlighted statement; previous steps remain unchanged.
Preparing the design walkthrough…
Implementation and expected output
Read the complete example alongside its input and expected output. The implementation selector changes the displayed program; the language selector preserves your current scenario and playback position.
Preparing the design walkthrough…
Try the idea in another setting
A file exporter can depend on a writer contract implemented by memory and disk writers.
- Name the new client contract before adapting the example.
- Identify which state belongs to each object and who controls its lifetime.
- Write one normal case and one boundary case before extending the design.
Tradeoffs and interview takeaways
Contracts help substitution only when semantics agree. JavaScript uses duck typing here; Python uses a small abstract base class. Neither style excuses incompatible error behavior.
Common mistake: Branching on a provider name inside the caller couples business logic to concrete delivery types.
- Explain the choice: Both senders implement send(message), and the caller receives a sender through its constructor.
- Challenge your choice: Contracts help substitution only when semantics agree. JavaScript uses duck typing here; Python uses a small abstract base class. Neither style excuses incompatible error behavior.
- Describe a requirement that would make the simpler implementation sufficient.
Design challenge and knowledge check
Preparing the design walkthrough…