Bridge Pattern

The Bridge Pattern, also known as the Handle and Body pattern or Interface pattern, is used to decouple abstraction from implementation, allowing them to vary independently. This type of design pattern belongs to the structural pattern and achieves decoupling between abstraction and implementation by providing a bridge structure.

Description

If we need to draw shapes such as rectangles, circles, ovals, and squares, we would need at least 4 shape classes. However, if the shapes need to have different colors like red, green, and blue, there are at least two design options: the first option is to provide a set of versions of each shape for each color, and the second option is to combine shapes and colors as needed. For a system with two dimensions of change (i.e., two reasons for change), using the second option to design the system requires fewer classes and facilitates system extension. This is the application of the bridge pattern, which transforms the inheritance relationship into an association relationship, reducing the coupling between classes and reducing the amount of code to be written.

Pattern Structure

  • Abstraction: Abstract class.
  • RefinedAbstraction: Refined abstract class.
  • Implementor: Implementation interface class.
  • ConcreteImplementor: Concrete implementation class.

Advantages

  • Separation of the abstract interface and its implementation part.
  • The bridge pattern is sometimes similar to a multiple inheritance scheme, but the multiple inheritance scheme violates the single responsibility principle of a class (i.e., a class has only one reason to change), has poor reusability, and results in a large number of classes in a multiple inheritance structure. The bridge pattern is a better solution than the multiple inheritance scheme.
  • The bridge pattern enhances the system's extensibility. Adding an extension to either of the two dimensions of change does not require modification of the original system.
  • The implementation details are transparent to the client and can hide implementation details from the user.

Disadvantages

  • The introduction of the bridge pattern increases the complexity of understanding and designing the system. Since the aggregate association relationship is established at the abstract layer, developers are required to design and program based on abstraction.
  • The bridge pattern requires the correct identification of the two independent dimensions of change in the system, thus its scope of use has certain limitations.

Pattern Analysis

  • Abstraction: Abstraction means ignoring some information and treating different entities as the same entity. In object-oriented programming, the process of extracting common properties of objects to form a class is abstraction.
  • Implementation: Giving specific implementation for the abstraction is implementation. Abstraction and implementation are a pair of mutually reversible concepts. The objects generated by implementation are more specific than the abstracted things and are the product of further concretizing the abstraction.
  • Decoupling: Decoupling refers to uncoupling the coupling between abstraction and implementation, or changing the strong association between them into a weak one, changing the inheritance relationship between the two roles into an association relationship. In the bridge pattern, the so-called decoupling refers to the use of an association relationship (composition or aggregation) rather than an inheritance relationship between abstraction and implementation, allowing them to change relatively independently, which is the purpose of the bridge pattern.

Applicable Scenarios

  • When a system needs to add more flexibility between the abstract and concrete roles of a component, avoiding establishing a static inheritance relationship between the two levels, the bridge pattern allows them to establish an association relationship at the abstract level.
  • The abstract role and concrete role can be independently extended in an inheritance manner without affecting each other. At runtime, a concrete subclass object of abstraction and a concrete subclass object of implementation can be dynamically combined, i.e., the system needs to dynamically couple the abstract role and the concrete role.
  • A class has two independent dimensions of change, and both dimensions need to be extended.
  • Although using inheritance in the system is not a problem, because the abstract role and the concrete role need to change independently, the design requires independent management of these two elements.
  • For systems that do not want to use inheritance or in cases where multi-level inheritance leads to a sharp increase in the number of system classes, the bridge pattern is especially suitable.

Implementation

class Shape {
    draw(){
        console.log(this.shape);
    }
    fill(color){
        this.color = color;
    }
}

class Rectangle extends Shape{
    constructor(){
        super();
        this.shape = "Rectangle";
    }
}

class Square extends Shape{
    constructor(){
        super();
        this.shape = "Square";
    }
}

class Circle extends Shape{
    constructor(){
        super();
        this.shape = "Circle";
    }
}

class Color {
    fill(){
        console.log(this.color);
    }
}

class Red extends Color{
    constructor(){
        super();
        this.color = "Red";
    }
}

class Green extends Color{
    constructor(){
        super();
        this.color = "Green";
    }
}

class Blue extends Color{
    constructor(){
        super();
        this.color = "Blue";
    }
}
class Bridge {
  constructor(shape, color) {
    this.shape = shape;
    this.color = color;
    this.shape.fill(color);
  }
  draw() {
    this.shape.draw();
    this.color.fill();
  }
}

(function() {
  var product = new Bridge(new Rectangle(), new Red());
  product.draw(); // Rectangle Red
  var product = new Bridge(new Square(), new Green());
  product.draw(); // Square Green
  var product = new Bridge(new Circle(), new Blue());
  product.draw(); // Circle Blue
})();

Daily Question

https://github.com/WindrunnerMax/EveryDay

References

https://segmentfault.com/a/1190000012547750 https://www.runoob.com/design-pattern/bridge-pattern.html https://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/bridge.html