Java Structural Design Patterns – Bridge Pattern
Bridge Pattern is one of the structural design patterns. As the name of the pattern is BRIDGE , it divides one class in 2 parts i.e., Abstraction and Implementation and acts as a Bridge between them, so that each can be developed and modified independently.
We can say that Bridge pattern provides loose coupling between Abstraction and Implementation, in future both the classes can change without affecting each other and client code can use only the one part i.e. Abstraction part without being concerned about the second part i.e. Implementation part.
In your application if you observe below points then you can use Bridge Pattern.
- abstraction and its implementation should be defined independently from each other
- You don’t need compile-time binding between an abstraction and its implementation.
<Here are ALL Java Design Patterns, explained in detail with examples>
Bridge Pattern by Example
The pattern can be explained with the help of below components –
1. Abstraction (it’s a abstract class): It defined the abstract interface i.e. behaviour part. It also maintains the Implementer reference.
2. Refined Abstraction (it’s a normal class): It extends the interface defined by Abstraction.
3. Implementer (it’s an interface): Implementer defines the interface for implementation classes. This interface does not need to correspond directly to abstraction interface and can be very different. Abstraction provides an implementation in terms of operations provided by Implementer interface.
4. Concrete Implementer (it’s a normal class): It implements the Implementer interface.
As an example we will try to implement some simple classes for Car Assembly. Here we’re producing and assembling the two different types of CAR using Bridge design pattern.
Following diagram shows the decoupling of Car and Workshop (bridge). You can make change in any of the class given below without interfering other class.
Lets define an abstract class Car –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.opencodez.patterns.bridge; public abstract class Car { protected Workshop workShop1; protected Workshop workShop2; protected Car(Workshop workShop1, Workshop workShop2) { this.workShop1 = workShop1; this.workShop2 = workShop2; } abstract public void production_house(); } |
After this we will add 2 concrete classes –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
package com.opencodez.patterns.bridge; public class Maruti extends Car { public Maruti (Workshop workShop1, Workshop workShop2) { super(workShop1, workShop2); } @Override public void production_house() { System.out.print("Maruti Car "); workShop1.work(); workShop2.work(); } } |
and
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package com.opencodez.patterns.bridge; public class BMW extends Car { public BMW(Workshop workShop1, Workshop workShop2) { super(workShop1, workShop2); } @Override public void production_house() { System.out.print("BMW Car "); workShop1.work(); workShop2.work(); } } |
Below is the Implementer Interface
1 2 3 4 5 6 |
package com.opencodez.patterns.bridge; public interface Workshop { abstract public void work(); } |
and Implementations
1 2 3 4 5 6 7 8 9 10 |
public class Assemble implements Workshop { @Override public void work() { System.out.println(" Assembled."); } } |
1 2 3 4 5 6 7 8 9 10 |
package com.opencodez.patterns.bridge; public class Produce implements Workshop { @Override public void work() { System.out.print("Produced"); } } |
Running the example
Here is our demo client-
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package com.opencodez.patterns.bridge; public class BridgePatternDemo { public static void main(String[] args) { Car car1 = new Maruti(new Produce(), new Assemble()); car1.production_house(); Car car2 = new BMW(new Produce(), new Assemble()); car2.production_house(); } } |
Output
1 2 |
Maruti Car Produced Assembled. BMW Car Produced Assembled. |
Conclusion
So this is all about Bridge Pattern, this pattern gives simple way to separate the abstraction and implementation which allows easy future extension and modification because this pattern removes dependency between abstraction and implementation.
Here are ALL other Java Design Patterns, explained in detail with examples