# Bridge - Design Pattern

> If get to know something new by reading my articles, don't forget to endorse me on [LinkedIn](https://www.linkedin.com/in/rommansabbir/)

# What is Bridge Design Pattern?

**"Decouple an abstraction from its implementation so that the two can vary independently."**

When we use inheritance, we are permanently binding the implementation to the abstraction. As a result, any change made to one affects the other. A more flexible way is to separate the abstraction and the implementation, and this is where the bridge pattern comes in.

The objective of the bridge pattern is to identify how to realize relationships between classes and objects in a simple way. The bridge pattern does it by separating the abstraction and the implementation in separate class hierarchies. The bridge between the class hierarchies is achieved through composition.

Let's deep dive into Bridge Design Pattern.

![bridge_1.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1642947169400/Oib-Cx_aY.png align="left")

Take a look at the above diagram, We see an abstract class `Message` which is extended by `TextMessage` and `EmailMessage`. Now, both `TextMessage` and `EmailMessage` is extended by `TextMessageSender` and `EmailMessageSender` respectively.

Everything is okay, right? Is there anything wrong with the design?

Notice that the abstraction part and the implementation part are tightly coupled. Our design relies on inheritance and one inherent disadvantages is that it breaks encapsulation.

What if client want's to add new layer of Encryption before sending the Message?. We need to update the abstraction part to make encryption functionality available to clients.

Another issue is reusability. If we want to reuse only the implementation (message sending) part in some other application, we will have to take along the abstraction part as extra baggage.

The bridge pattern addresses all such issues by separating the abstraction and implementation into two class hierarchies.

![bridge_2.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1642947755194/FRosmieBI.png align="left")

Now take look at the above diagram.

With the bridge pattern, the abstraction maintains a **Has-A relationship** with the implementation instead of a **IS-A relationship**. The **Has-A relationship** is achieved through composition where the abstraction maintains a reference of the implementation and forwards client requests to it.

Okay, lets get into coding part.

```plaintext
interface MessageSender {
    fun sendMessage()
}
```

```plaintext
abstract class Message(internal val sender: MessageSender) {
    abstract fun send()
}
```

```plaintext
class TextMessage(messageSender: MessageSender) : Message(messageSender) {
    override fun send() { sender.sendMessage() }
}
```

```plaintext
class EmailMessage(messageSender: MessageSender) : Message(messageSender) {
    override fun send() { sender.sendMessage() }
}
```

We have an abstract class `Message` which takes `MessageSender` as a parameter (**Composition**) and one abstract method `send()`.

`TextMessage`, `EmailMessage` both extend `Message` and override the `send()` method and we are using the `MessageSender` object to send message (**Text/Email**).

Here, we are not tightly coupled to another subsystem, instead we followed **Compositon**.

```plaintext
class TextMessageSender : MessageSender {
    override fun sendMessage() {
        println("TextMessageSender: Sending text message...")
    }
}
```

```plaintext
class EmailMessageSender : MessageSender {
    override fun sendMessage() {
        println("EmailMessageSender: Sending email message...")
    }
}
```

Now, we have implementation of `MessageSender` for **Text** and **Email Message**. We, decoupled the nested logic which has been shown in the 1st diagram.

`TextMessageSender` and `EmailMessageSender` are the concrete classes of `MessageSender`. Now we can add **Encryption** before sending Message without any changes in Base.

Let's test it.

```plaintext
val textMessageSender: MessageSender = TextMessageSender()
val textMessage: Message = TextMessage(textMessageSender)
textMessage.send()
//Result - TextMessageSender: Sending text message...

val emailMessageSender: MessageSender = EmailMessageSender()
val emailMessage: Message = EmailMessage(emailMessageSender)
emailMessage.send()
//Result - EmailMessageSender: Sending email message...
```

Finally, we did it. Now `Message` **Has-A Relationship** with `MessageSender` instead of **Is-A Relationship** and separated the abstraction and the implementation in separate class hierarchies.

Now, let's take a look at the full implementation in Kotlin.

%[https://gist.github.com/rommansabbir/c8522df36e0255202b62305479f628f8] 

Follow me on LinkedIn

%[https://www.linkedin.com/in/rommansabbir/]
