One of the structural patterns, the Bridge Pattern, decouples an abstraction from its implementation so that two can vary independently. The bridge uses encapsulation, aggregation and also it can use inheritance to separate responsibilities into different classes.
The Bridge Pattern can be thought of as two layers of abstraction. This pattern involves an interface which acts as a bridge which makes the functionality of concrete classes independent from interface implementer classes. Both types of classes can be altered structurally without affecting each other.
Decouple implementation from interface and hiding implementation details from client is the purpose of bridge design pattern.
The abstraction is an interface or abstract class and contains a reference to the implementer.
The refined abstraction is the child of the abstraction and takes finer details one level below. It hides the finer elements from implementers.
The implementer is likewise an interface or abstract class and higher level abstraction with basic operations.
Concrete implementers provide concrete implementation at run-time by implementing the above implementer.
Class Diagram
The display of different formats of images on different operating systems is an example of the Bridge pattern. We might have different image abstractions for both jpg, png and gif images. The image structure is same across all operating systems, but how the image will be viewed is different on each Operating System(OS). This is the type of decoupling that the Bridge pattern allows. The following example demonstrates this pattern
First we have our below OS interface
package com.roytuts.designpattern.bridge; public interface OS { void displayJPGImage(); void displayPNGImage(); void displayGIFImage(); }
Next we create two different implementations – one for Windows OS and another for Mac OS. These classes deal with specific implementations of displaying different images from each vendor.
package com.roytuts.designpattern.bridge; public class WindowsOS implements OS { @Override public void displayJPGImage() { //WindowsOS specific implementation for displaying jpg image System.out.println("WindowsOS displays JPG image"); } @Override public void displayPNGImage() { //WindowsOS specific implementation for displaying png image System.out.println("WindowsOS displays PNG image"); } @Override public void displayGIFImage() { //WindowsOS specific implementation for displaying gif image System.out.println("WindowsOS displays GIF image"); } }
package com.roytuts.designpattern.bridge; public class MacOS implements OS { @Override public void displayJPGImage() { //MacOS specific implementation for displaying jpg image System.out.println("MacOS displays JPG image"); } @Override public void displayPNGImage() { //MacOS specific implementation for displaying png image System.out.println("MacOS displays PNG image"); } @Override public void displayGIFImage() { //MacOS specific implementation for displaying gif image System.out.println("MacOS displays GIF image"); } }
Now we will create an abstraction for displaying image.
package com.roytuts.designpattern.bridge; public abstract class OSImage { protected OS os; protected OSImage(OS os) { this.os = os; } public abstract void displayImage(); }
As the OSImage holds a reference to the OS, it can delegates the methods through to the interface. But what is we want a more specific functionality to contain these concepts:
package com.roytuts.designpattern.bridge; public class ConcreteOS extends OSImage { public ConcreteOS(OS os) { super(os); } @Override public void displayImage() { os.displayJPGImage(); os.displayPNGImage(); os.displayGIFImage(); } }
Test the above pattern by creating the below test class
package com.roytuts.designpattern.bridge; public class BridgePatternTest { /** * @param args */ public static void main(String[] args) { OSImage windowsImage = new ConcreteOS(new WindowsOS()); OSImage macImage = new ConcreteOS(new MacOS()); windowsImage.displayImage(); System.out.println(); macImage.displayImage(); } }
Run the above class and see the below output.
Output
WindowsOS displays JPG image WindowsOS displays PNG image WindowsOS displays GIF image MacOS displays JPG image MacOS displays PNG image MacOS displays GIF image
That’s all. Thank you for your reading.