The Bridge pattern is implemented by splitting a class hierarchy into two independent hierarchies: an abstraction and an implementation, connected through composition rather than inheritance. This lets you vary the high-level behavior and the low-level implementation separately.
Key Points: • Define an implementor interface that declares the low-level operations. • Create concrete implementor classes, one per implementation variant. • Define an abstraction class that holds a reference to the implementor interface. • Extend the abstraction with refined abstractions that add higher-level behavior. • Changes to either hierarchy do not force changes in the other, avoiding a combinatorial explosion of subclasses.
Example: A remote control (abstraction) can operate different devices (implementor) such as a TV or a radio; instead of creating a TVRemote and RadioRemote subclass pair for every combination, the remote just holds a Device reference and delegates turnOn()/turnOff() to it.
Code Example:
interface Device {
void turnOn();
void turnOff();
}
class Tv implements Device {
public void turnOn() { System.out.println("TV on"); }
public void turnOff() { System.out.println("TV off"); }
}
abstract class RemoteControl {
protected Device device;
protected RemoteControl(Device device) {
this.device = device;
}
public abstract void power();
}
class BasicRemote extends RemoteControl {
public BasicRemote(Device device) { super(device); }
public void power() {
device.turnOn();
}
}Interview Tip: A concise interview answer is:
"I split the class into an abstraction hierarchy and an implementation hierarchy connected through a composed interface rather than inheritance. The abstraction holds a reference to the implementor, so I can mix and match abstractions and implementations independently instead of creating a subclass for every combination."