Bridge pattern

The bridge decouples an abstraction from its implementation so that the two can vary independently.

problems

Suppose we have some abstraction and its subclasses. For example, abstract class MessageA and two subclasses TextMessage and EmailMessage. And now we want functionality for sending message. What we can do?

We can extends TextMessage and EmailMessage classes to TextMessageSender and EmailMessageSender classes. But thus, we break encapsulation - TextMessageSender knows the internals of TextMessage. And we have dependencies, TextMessageSender cannot be used without TextMessage class. And finally, we cannot change the send function without updating our classes, for example, send an encrypted message.

The bridge pattern solves these problems. To do this, we add a second abstraction - the MessageSenderA class from which the TextMessageSender and EmailMessageSender classes will be inherited. Then add a reference to the MessageSenderA in the TextMessageA class. Now the message abstraction will be separated from the message sending implementation.

advantages

  1. Decouples an abstraction from its implementation.
  2. Makes code cleaner.
  3. Improves extensibility.

example

// first abstraction 
public abstract class TextMessageA {
    // our bridge: TextMessageA has a MessageSenderA
    MessageSenderA messageSender;
    
    public TextMessageA(MessageSenderA sender){
        messageSender = sender;
    }
    // ...
}

// concrete subclasses
public class TextMessage extends TextMessageA { /* ... */ }
public class EmailMessage extends TextMessageA { /* ... */ }

// second abstraction
public abstract class MessageSenderA {
    public void sendMessage(){}
}

// concrete implementations of the message sending
public class TextMessageSender extends MessageSenderA {
    public void sendMessage(){}
}

public class EmailMessageSender extends MessageSenderA {
    public void sendMessage(){}
}

// using
MessageSenderA emailMessageSender = new EmailMessageSender();
MessageA emailMessage = new TextMessage(emailMessageSender);
emailMessage.send();