Original code
class NotificationDispatcher {
private sender = new EmailSender()
send(message: string) {
this.sender.send(message)
}
}High-level code decides what should happen; low-level code handles how it happens. Both depend on a shared interface, so the high-level code does not need to know a particular implementation.
NotificationDispatcher creates its own EmailSender. Using SMS or a test sender would require editing the dispatcher.
class NotificationDispatcher {
private sender = new EmailSender()
send(message: string) {
this.sender.send(message)
}
}interface Sender {
send(message: string): void
}
class NotificationDispatcher {
private sender: Sender
constructor(sender: Sender) {
this.sender = sender
}
send(message: string) {
this.sender.send(message)
}
}
const dispatcher = new NotificationDispatcher(new EmailSender())Sources: Martin on Single Responsibility, Robert C. Martin’s design principles, and Liskov and Wing on behavioral subtyping.