Bridge Design Pattern is used to decouples an abstraction used the client code from its implementation that means it separates the abstraction and its implementation in separate class hierarchies. And also Bridge pattern prefers the composition over the inheritance because inheritance isn’t always flexible and it breaks the encapsulation, so any change made in the implementor that affects the abstraction used by client code.
In software engineering, one of popular notion is “prefer composition over inheritance“. Bridge design pattern promotes this popular notion. Similar to the other pattern, this pattern also comes under the structural design pattern family of GoF Design pattern.
According to the Gang of Four:
Decouple an abstraction from its implementation so that the two can vary independently.
Bridge pattern uses an interface as bridge between the concrete classes of an abstract class and implementing classes of that interface. You can make changes in both types of classes without any impact on the client code.
There are following common problems solved by the Bridge Design Pattern.
also read:
Let’s see the following class diagram. It illustrates about the component classes and interfaces.
The classes and objects participating in this pattern are:
Abstraction (Bank)
RefinedAbstraction (IciciBank, HdfcBank)
Implementor (Account)
ConcreteImplementor (CurrentAccount, SavingAccount)
There are following pros of the Bridge Design Pattern.
The adapter design pattern helps it two incompatible classes to work together. But, bridge design pattern decouples the abstraction and implementation by creating two different hierarchies.
You look in the following example where I am going to demonstrate use of Bridge design pattern. Here I am taking two accounts of any Bank, you can open two types of accounts one is SavingAccount and other is CurrentAccount. Let’s see the relationship between the abstraction of a Bank and Account.
Let’s start to create a design without using Bridge Design Pattern. First create an interface or an abstract class, Bank. And then I create its derived classes: IciciBank and HdfcBank. To open an account in bank, first decide type of accounts classes: SavingAccount and CurrentAccount, these classes extends the specific banks classes (HdfcBank and IciciBank). This simple deep inheritance hierarchy in this application.
So what is wrong with this design as below figure. You will notice in this design, there are two parts, one is the abstraction part and other is the implementation part. Client code interacts with the abstraction part. Client code can only access new change or new functionality of the implementation part when you will update the abstraction part, it means both parts the abstraction and implementation are tightly coupled with each-other.
Let’s look into the following figure, how Bridge design pattern solve these design issues as noticed in the without using bridge pattern example. Bridge pattern is separating the abstraction and implementation into two class hierarchies.
We have a Account interface which is acting as a bridge implementer and concrete classes SavingAccount, CurrentAccount implementing the Account interface. Bank is an abstract class and will use object of Account.
Account.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Implementor for bridge pattern */ public interface Account { Account openAccount(); void accountType(); }
CurrentAccount.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Concrete implementation 1 for bridge pattern */ public class CurrentAccount implements Account { @Override public Account openAccount() { System.out.println("OPENED: CURRENT ACCOUNT "); return new CurrentAccount(); } @Override public void accountType() { System.out.println("##It is a CURRENT Account##"); } }
SavingAccount.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Concrete implementation 2 for bridge pattern */ public class SavingAccount implements Account { @Override public Account openAccount() { System.out.println("OPENED: SAVING ACCOUNT "); return new SavingAccount(); } @Override public void accountType() { System.out.println("##It is a SAVING Account##"); } }
Bank.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Abstraction in bridge pattern */ public abstract class Bank { //Composition with implementor protected Account account; public Bank(Account account){ this.account = account; } abstract Account openAccount(); }
IciciBank.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Refine abstraction 1 in bridge pattern */ public class IciciBank extends Bank { public IciciBank(Account account) { super(account); } @Override Account openAccount() { System.out.print("Open your account with ICICI Bank"); return account; } }
HdfcBank.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Refine abstraction 2 in bridge pattern */ public class HdfcBank extends Bank { public HdfcBank(Account account) { super(account); } @Override Account openAccount() { System.out.print("Open your account with HDFC Bank"); return account; } }
BridgePatternMain.java
package com.doj.patterns.structural.bridge; /** * @author Dinesh.Rajput * Demonstration of bridge design pattern */ public class BridgePatternMain { public static void main(String[] args) { Bank icici = new IciciBank(new CurrentAccount()); Account current = icici.openAccount(); current.accountType(); Bank hdfc = new HdfcBank(new SavingAccount()); Account saving = hdfc.openAccount(); saving.accountType(); } }
Open your account with ICICI Bank##It is a CURRENT Account## Open your account with HDFC Bank##It is a SAVING Account##
Strategy Design Patterns We can easily create a strategy design pattern using lambda. To implement…
Decorator Pattern A decorator pattern allows a user to add new functionality to an existing…
Delegating pattern In software engineering, the delegation pattern is an object-oriented design pattern that allows…
Technology has emerged a lot in the last decade, and now we have artificial intelligence;…
Managing a database is becoming increasingly complex now due to the vast amount of data…
Overview In this article, we will explore Spring Scheduler how we could use it by…