Bridge pattern decouples abstraction from implementation so that both can vary independently. It has been achieved with composition rather than inheritance.
Bridge UML diagram from wikipedia:
You have four components in this pattern.
Abstraction
: It defines an interface
RefinedAbstraction
: It implements abstraction:
Implementor
: It defines an interface for implementation
ConcreteImplementor
: It implements Implementor interface.
The crux of Bridge pattern :
Two orthogonal class hierarchies using composition (and no inheritance). The Abstraction hierarchy and Implementation hierarchy can vary independently. Implementation never refers Abstraction. Abstraction contains Implementation interface as a member (through composition). This composition reduces one more level of inheritance hierarchy.
Real word Use case:
Enable different vehicles to have both versions of manual and auto gear system.
Example code:
/* Implementor interface*/
interface Gear{
void handleGear();
}
/* Concrete Implementor - 1 */
class ManualGear implements Gear{
public void handleGear(){
System.out.println("Manual gear");
}
}
/* Concrete Implementor - 2 */
class AutoGear implements Gear{
public void handleGear(){
System.out.println("Auto gear");
}
}
/* Abstraction (abstract class) */
abstract class Vehicle {
Gear gear;
public Vehicle(Gear gear){
this.gear = gear;
}
abstract void addGear();
}
/* RefinedAbstraction - 1*/
class Car extends Vehicle{
public Car(Gear gear){
super(gear);
// initialize various other Car components to make the car
}
public void addGear(){
System.out.print("Car handles ");
gear.handleGear();
}
}
/* RefinedAbstraction - 2 */
class Truck extends Vehicle{
public Truck(Gear gear){
super(gear);
// initialize various other Truck components to make the car
}
public void addGear(){
System.out.print("Truck handles " );
gear.handleGear();
}
}
/* Client program */
public class BridgeDemo {
public static void main(String args[]){
Gear gear = new ManualGear();
Vehicle vehicle = new Car(gear);
vehicle.addGear();
gear = new AutoGear();
vehicle = new Car(gear);
vehicle.addGear();
gear = new ManualGear();
vehicle = new Truck(gear);
vehicle.addGear();
gear = new AutoGear();
vehicle = new Truck(gear);
vehicle.addGear();
}
}
output:
Car handles Manual gear
Car handles Auto gear
Truck handles Manual gear
Truck handles Auto gear
Explanation:
Vehicle
is an abstraction.Car
and Truck
are two concrete implementations of Vehicle
.Vehicle
defines an abstract method : addGear()
.Gear
is implementor interfaceManualGear
and AutoGear
are two implementations of Gear
Vehicle
contains implementor
interface rather than implementing the interface. Compositon
of implementor interface is crux of this pattern : It allows abstraction and implementation to vary independently.Car
and Truck
define implementation ( redefined abstraction) for abstraction : addGear()
: It contains Gear
- Either Manual
or Auto
Use case(s) for Bridge pattern: