Bridge Pattern

Last Updated on September 24, 2023 by KnownSense

The Bridge pattern is like a blueprint for organizing big classes or groups of related classes. It helps you separate them into two distinct parts: one for their main features (abstraction) and another for how they actually work (implementation). This separation allows you to work on these parts independently, making your code more flexible and easier to maintain.

In smartphones, there are various functionalities such as making calls, sending messages, and taking photos. These functionalities can vary greatly depending on the phone’s operating system (e.g., Android, iOS) and the hardware it’s running on.

By using the Bridge pattern, smartphone developers can design the user-facing features (abstraction) independently of the specific hardware and software details (implementation). This separation allows them to add new features, update the user interface, or improve performance without needing to rewrite the entire codebase for each different phone model or operating system version.

Benefits

  1. Separation of Abstraction and Implementation: The primary advantage of the Bridge pattern is its ability to separate the high-level abstraction from the low-level implementation. This separation allows these two components to evolve independently, making the code more flexible and adaptable to changes.
  2. Improved Code Reusability: Because the abstraction and implementation are decoupled, you can reuse both components in different contexts. You can have multiple abstractions using the same implementation or vice versa, which promotes code reuse and minimizes redundancy.
  3. Enhanced Maintainability: When you need to make changes or updates to either the abstraction or implementation, you can do so without affecting the other part of the codebase. This simplifies maintenance and reduces the risk of introducing bugs during updates.
  4. Platform and Device Independence: In cases where your software needs to run on different platforms or devices with varying implementations, the Bridge pattern is particularly useful. It allows you to create platform-specific implementations while keeping a consistent abstraction layer.
  5. Adaptability to Future Changes: As technology evolves, hardware and software components may change or be replaced. The Bridge pattern makes it easier to adapt your code to new technologies without rewriting the entire application. You can create new implementations for the new components and connect them to the existing abstraction.
  6. Enhanced Testing: Separating abstraction from implementation simplifies unit testing. You can create mock implementations for testing the abstraction independently, ensuring that the high-level logic functions correctly.
  7. Reduction of Code Complexity: By breaking down complex classes into smaller, manageable components, the Bridge pattern reduces the complexity of your code. This makes it easier to understand, maintain, and extend your software.
  8. Scalability: The Bridge pattern is beneficial for systems that need to scale by adding new features or support for different types of implementations. You can introduce new abstractions and implementations without disrupting the existing code.
  9. Consistent User Experience: In user-facing applications, the Bridge pattern helps maintain a consistent user experience while allowing for variations in the underlying implementations. Users can interact with the same high-level features regardless of the specific implementation details.

UML for Bridge Pattern

Bridge Pattern

Implementation

Now, we will implement the smartphone functionalities for different operating system

Step1: Create a Interface named OperatingSystem

public interface OperatingSystem {
    String getOperationSystem();
}

Step2: Create concrete classes for different types of OS that implements OperatingSystem interface

public class AndroidOS implements OperatingSystem {
    @Override
    public String getOperationSystem() {
        return "Android OS";
    }
}
public class IOS implements OperatingSystem {
    @Override
    public String getOperationSystem() {
        return "iOS";
    }
}

Step3: Create a abstract class SmartPhone that has instance of OperatingSystem and method for functionalities of smartPhone

public abstract class Smartphone {
    protected OperatingSystem os;

    public Smartphone(OperatingSystem os) {
        this.os = os;
    }

    public abstract void makeCall();

    public abstract void sendMessage();
}

Step4: Create concrete classes for different mobiles that extends the Smartphone abstract class.

public class IPhone extends Smartphone {
    public IPhone(OperatingSystem os) {
        super(os);
    }

    @Override
    public void makeCall() {
        System.out.println("Making a call using a smartphone with " + os.getOperationSystem());
    }

    @Override
    public void sendMessage() {
        System.out.println("Sending a message using a smartphone with " + os.getOperationSystem());
    }
}
public class AndroidPhone extends Smartphone {
    public AndroidPhone(OperatingSystem os) {
        super(os);
    }

    @Override
    public void makeCall() {
        System.out.println("Making a call using a smartphone with " + os.getOperationSystem());
    }

    @Override
    public void sendMessage() {
        System.out.println("Sending a message using a smartphone with " + os.getOperationSystem());
    }
}

Step5: In main class we will use the operatingSystem and Smartphone instances

public class BridgePattern {

    public static void main(String[] args) {
        OperatingSystem androidOS = new AndroidOS();
        OperatingSystem iOS = new IOS();

        Smartphone androidPhone = new AndroidPhone(androidOS);
        Smartphone iPhone = new IPhone(iOS);

        androidPhone.makeCall();
        androidPhone.sendMessage();

        iPhone.makeCall();
        iPhone.sendMessage();
    }
}

Conclusion

In conclusion, the Bridge Pattern is a structural design pattern that promotes decoupling by separating an abstraction from its implementation. It allows you to develop and evolve these two components independently, providing flexibility and ease of maintenance in software systems. By employing the Bridge Pattern, you can create hierarchies of abstractions and implementations, enabling various combinations and customization options for your software components.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top