Where and how to use Bridge Design Pattern ?

Where and how to use Bridge Design Pattern ?

The Bridge design pattern helps break down a big class or a group of closely linked classes into two parts: abstraction and implementation. These part

The Bridge pattern is like building a bridge between two different parts of your program. It helps keep things flexible and easy to change by separating what something does from how it's actually done.

Here's a simpler explanation:

  1. Abstraction: Think of this as what you want to do. It's like saying, "I want to make a drawing."

  2. Implementor: This is how you actually do it. It's like saying, "I will use a pencil to draw."

  3. Refined Abstraction: This is when you get more specific about what you want to do. For example, "I want to draw a house."

  4. Concrete Implementor: This is the specific way you actually do it. It's like saying, "I will use a pencil to draw the house."

The Bridge pattern helps you make changes without causing big problems. For example, if you want to change from using a pencil to using a pen, you can do it without changing how you draw or what you draw. You just need to adjust the implementor part (like switching from a pencil to a pen) while keeping the abstraction part (like drawing a house) the same.

Let's consider an example scenario where we want to develop a drawing application that can draw shapes on different platforms, such as Windows and Mac OS. We'll use the Bridge design pattern to solve the problem of coupling between the drawing abstraction and its implementation on different platforms.

Problem :

We want to design a solution that allows smart keys to work with different car models without tightly coupling the key functionality to the specific car models. We need to ensure that adding new car models or changing the functionality of the smart key doesn't require extensive modifications to the existing codebase.

Solution using Bridge Design Pattern :

We can use the Bridge design pattern to decouple the abstraction of the smart key from its implementation for different car models. This involves defining an abstraction for the smart key functionality and separate implementors for each car model. By doing so, we can vary the smart key behavior independently of the car models and vice versa.

Example :

Let's delve deeper into the Kotlin code and its implementation using the Bridge design pattern for the car smart key problem:

1. Car Model Implementors:

interface CarModel {
    fun unlock()
    fun lock()
}

class Toyota : CarModel {
    override fun unlock() {
        println("Unlocking Toyota car.")
    }

    override fun lock() {
        println("Locking Toyota car.")
    }
}

class Honda : CarModel {
    override fun unlock() {
        println("Unlocking Honda car.")
    }

    override fun lock() {
        println("Locking Honda car.")
    }
}
  • The CarModel interface defines methods unlock() and lock() representing the actions specific to each car model.

  • Toyota and Honda classes implement the CarModel interface, providing concrete implementations for unlocking and locking actions for Toyota and Honda cars, respectively.

2. Smart Key Abstraction and Refined Abstraction:

abstract class SmartKey(protected val carModel: CarModel) {
    abstract fun pressUnlockButton()
    abstract fun pressLockButton()
}

class CarSmartKey(carModel: CarModel) : SmartKey(carModel) {
    override fun pressUnlockButton() {
        carModel.unlock()
    }

    override fun pressLockButton() {
        carModel.lock()
    }
}
  • The SmartKey class serves as the abstraction for the smart key functionality. It contains methods like pressUnlockButton() and pressLockButton().

  • CarSmartKey is a refined abstraction that takes a CarModel object during initialization and delegates the unlocking and locking operations to it.

3. Example Usage:

fun main() {
    val toyotaSmartKey = CarSmartKey(Toyota())
    toyotaSmartKey.pressUnlockButton() // Output: Unlocking Toyota car.
    toyotaSmartKey.pressLockButton()   // Output: Locking Toyota car.

    val hondaSmartKey = CarSmartKey(Honda())
    hondaSmartKey.pressUnlockButton()  // Output: Unlocking Honda car.
    hondaSmartKey.pressLockButton()    // Output: Locking Honda car.
}
  • In the main function, we create instances of CarSmartKey for Toyota and Honda cars.

  • We then call the pressUnlockButton() and pressLockButton() methods on these smart key instances, which trigger the corresponding actions specific to each car model.

In this above implementation:

  • The Bridge pattern decouples the smart key abstraction (SmartKey) from its implementation for different car models (CarModel). This separation allows changes in smart key behavior or the addition of new car models without impacting existing code significantly.

  • Each car model has its concrete implementation (Toyota, Honda) of unlocking and locking actions, providing flexibility to handle specific functionalities for each car model.

  • The CarSmartKey class acts as a bridge between the smart key functionality and the car models, allowing the smart key to interact with different car models without knowing their specific implementations.

  • By utilizing the Bridge pattern, we achieve a modular and flexible design, facilitating easier maintenance and scalability of the smart key system.

Outcome :

  • Decoupling: The Bridge pattern decouples the abstraction of the smart key from its implementation for different car models, allowing changes in one to be independent of the other.

  • Flexibility: It enables easy integration of new car models and changes to the smart key behavior without extensive modifications to the existing codebase.

  • Maintainability: The code becomes more maintainable as the changes in car models or smart key functionality can be isolated to their respective hierarchies.

उद्यमेन हि सिध्यन्ति कार्याणि न मनोरथैः। न हि सुप्तस्य सिंहस्य प्रविशंति मुखे मृगाः।

कोई भी काम उद्यम ( मेहनत ) से ही पूरा होता है, बैठे-बैठे हवाई किले बनाने से नहीं अर्थात सिर्फ सोचने भर से नहीं। ठीक उसी प्रकार सोते हुए शेर के मुंह में हिरण खुद नहीं चला जाता।

Any work is accomplished by hard work, not just by thinking. In the same way, As the deer does not enter the mouth of the sleeping lion.