๐ Bridge Pattern
The Bridge pattern is a structural design pattern that explains how to assemble objects and classes into larger structures while keeping the structure flexible and efficient.
Overview
The Bridge pattern separates the abstraction and implementation parts of a system into separate classes. It allows them to vary independently and provides a bridge between them. The abstraction represents the higher-level functionality, while the implementation represents the lower-level details.
The key idea behind the Bridge pattern is to decouple the abstraction and implementation, allowing them to evolve independently. By using interfaces or abstract classes, the Bridge pattern enables the implementation and abstraction to vary independently.
Participants
The key participants in the Bridge pattern are:
Abstraction: The highest-level class in the abstraction hierarchy. It contains a reference to an object of the Implementor class and uses it to invoke the implementation's methods.
RefinedAbstraction: A subclass of the Abstraction class that adds additional functionality or refines the behavior defined by the Abstraction class.
Implementor: The interface or abstract class that defines the methods to be implemented by the ConcreteImplementor classes.
ConcreteImplementor: The classes that implement the Implementor interface or extend the Implementor abstract class. They provide the specific implementation of the methods defined by the Implementor.
In the example diagram above:
Animal
is the abstraction class that defines the high-level functionality.Tiger
andBird
are subclasses ofAnimal
that refine the abstraction and provide specific functionality.Hunting_Handler
is the interface that represents the implementation part.Hunting_Method1
andHunting_Method2
are concrete implementations ofHunting_Handler
that provide different hunting methods.
Implementor
interface Hunting_Handler {
find_Quarry();
detected_Quarry();
attack();
}
class Hunting_Method1 implements Hunting_Handler {
find_quarry() {
console.log("finding in water");
}
detected_quarry() {
console.log("found out fish");
}
attack() {
console.log("catch it");
}
}
class Hunting_Method2 implements Hunting_Handler {
find_quarry() {
console.log("finding on the land");
}
detected_quarry() {
console.log("found deer");
}
attack() {
console.log("bite it");
}
}
Abstraction
class Animal {
find_quarry() {
this.find_quarry();
}
detected_quarry() {
this.detected_quarry();
}
attack() {
this.attack();
}
hunt() {
this.find_quarry();
this.detected_quarry();
this.attack();
}
}
class Tiger extends Animal {
super();
}
class Bird extends Animal {
super();
}
๐ Why do we use the Bridge pattern?
We use the Bridge pattern to separate the abstraction and implementation parts of a system and allow them to vary independently. This provides several benefits:
Decoupling: The Bridge pattern decouples the abstraction from its implementation, allowing them to change independently. This improves the flexibility and maintainability of the code.
Extensibility: By separating the abstraction and implementation, it becomes easier to add new abstractions or implementations without modifying existing code. This makes the system more extensible.
Reduced Complexity: The Bridge pattern simplifies the system's design by breaking it down into smaller, manageable components. It promotes a clear separation of concerns and helps avoid a tangled hierarchy of classes.
Runtime Binding: The Bridge pattern allows the implementation to be selected or changed at runtime. This provides flexibility and allows the system to adapt to different scenarios or requirements.
Overall, the Bridge pattern promotes a modular and flexible design that is easier to understand, extend, and maintain. It is particularly useful when there is a need to decouple abstractions from their implementations and when the system's components are expected to evolve independently.