Bridge

Split abstraction from implementation

Bridge separates a thing (an abstraction) from how it's carried out (an implementation) so the two can vary independently. A Notification is the abstraction โ€” it has a message and a recipient. The Transport (SMS, email) is the implementation. Either axis can grow without touching the other.

Instead of subclassing Notification into SmsNotification, EmailNotification, you inject the transport. New transports and new notification types no longer multiply into a combinatorial mess.