Bridge Design Pattern
Bridge design pattern is used when there is a hierarchy in abstraction as well as in its implementations. It is used to decouple abstraction from its implementation so that both can vary independent of each other.
For example, there is a remote interface. Below is the hierarchy in this abstraction. So, you can see that there is a complete hierarchy in remote such as TVRemote, ToyCarRemote, NormalRemote etc. Whereas, there is a complete hierarchy in devices as well: TV, SmartTV, ToyCar. Now, you can see that both the hierarchies can grow independently. The relationship between the top interfaces Remote and RemoteControllable works as a bridge here.
Remote interfaces hierarchy
Remote interface
package com.sks.bridge;
public interface Remote {
void turnOnDevice();
void turnOffDevice();
}
TVRemote interface
package com.sks.bridge;
public interface TVRemote extends Remote {
void increaseVolumeOfDevice();
void decreaseVolumeOfDevice();
}
ToyCarRemote
package com.sks.bridge;
public interface ToyCarRemote extends Remote {
void move();
}
Remote controlled devices hierarchy
RemoteControllable interface
package com.sks.bridge;
public interface RemoteControllable extends Remote {
}
abstract Device class that implements RemoteControllable interface
package com.sks.bridge;
public abstract class Device implements RemoteControllable {
protected String name;
@Override
public void turnOnDevice() {
System.out.println(name + " is turned on");
}
@Override
public void turnOffDevice() {
System.out.println(name + " is turned off");
}
public Device(String name) {
super();
this.name = name;
}
}
Concrete class TV
package com.sks.bridge;
public class TV extends Device {
public void increaseVolumeOfDevice() {
System.out.println(this.name + "'s volume is up by one point");
}
public void decreaseVolumeOfDevice() {
System.out.println(this.name + "'s volume is down by one point");
}
public TV(String name) {
super(name);
}
}
SmartTV class
package com.sks.bridge;
public class SmartTV extends TV{
public void playYouTube() {
System.out.println("Smart tv is playing Youtube");
}
public SmartTV(String name) {
super(name);
}
}
ToyCar class
package com.sks.bridge;
public class ToyCar extends Device {
public ToyCar(String name) {
super(name);
}
public void move() {
System.out.println(this.name + " is moving");
}
}
Remote implementation classes
NormalRemote class
package com.sks.bridge;
public class NormalRemote implements Remote {
protected Device device;
public NormalRemote(Device device) {
this.device = device;
}
@Override
public void turnOnDevice() {
System.out.println("Normal remote is turning on " + this.device.name);
this.device.turnOnDevice();
}
@Override
public void turnOffDevice() {
System.out.println("Normal remote is turning off " + this.device.name);
this.device.turnOffDevice();
}
}
TVRemoteImpl
package com.sks.bridge;
public class TVRemoteImpl extends NormalRemote implements TVRemote {
private TV tv;
public TVRemoteImpl(TV tv) {
super(tv);
this.tv = tv;
}
@Override
public void increaseVolumeOfDevice() {
this.tv.increaseVolumeOfDevice();
}
@Override
public void decreaseVolumeOfDevice() {
this.tv.decreaseVolumeOfDevice();
}
}
SmartTV remote
package com.sks.bridge;
public class SmartTVRemote extends TVRemoteImpl {
public SmartTVRemote(TV tv) {
super(tv);
}
public void playYouTube() {
System.out.println("Playing youtube on " + device.name);
}
}
ToyCarRemoteImpl class
package com.sks.bridge;
public class TVRemoteImpl extends NormalRemote implements TVRemote {
private TV tv;
public TVRemoteImpl(TV tv) {
super(tv);
this.tv = tv;
}
@Override
public void increaseVolumeOfDevice() {
this.tv.increaseVolumeOfDevice();
}
@Override
public void decreaseVolumeOfDevice() {
this.tv.decreaseVolumeOfDevice();
}
}
Bridge pattern testing class
package com.sks.bridge;
public class BridgePatternTest {
public static void main(String[] args) {
TV tv = new TV("Sony Bravia");
TVRemote remote = new TVRemoteImpl(tv);
remote.turnOnDevice();
remote.increaseVolumeOfDevice();
SmartTV tv1 = new SmartTV("Oneplus Smart TV");
SmartTVRemote remote1 = new SmartTVRemote(tv1);
remote1.playYouTube();
ToyCar toyCar = new ToyCar("Red Toy Car");
ToyCarRemote remote2 = new ToyCarRemoteImpl(toyCar);
remote2.turnOnDevice();
remote2.move();
}
}
Output :