Github source address

An overview of 23 design patterns

  • Java Language Design – An overview of 23 design patterns

Creation pattern

  • Factory Method Pattern
  • Abstract Factory Pattern
  • Builder Mode
  • Prototype mode
  • Singleton

Structural mode

  • Facade Pattern
  • Adapter mode (Adapter)
  • Proxy mode
  • Composite mode
  • Flyweight Mode
  • Decorator pattern
  • Bridge mode (Bridge)

Behavioral pattern

  • Mediator Mode
  • Observer Model
  • Command mode
  • Iterator pattern (Iterator)
  • Template Method
  • Strategy Pattern
  • State mode
  • Memento Mode
  • Interpreter mode
  • Chain of Responsibility model
  • Visitor Pattern

define

Bridges are used to decouple abstractions from implementations so that they can vary independently. This type of design pattern is structural in that it decouples abstraction and implementation by providing a bridge between them.

This pattern involves an interface that acts as a bridge, making the functionality of the entity class independent of the interface implementation class. These two types of classes can be structurally altered without affecting each other.

Key code: Abstract classes depend on implementation classes.

The bridge mode can be understood in two ways:

  • Decouple abstractions and implementations so they can be developed independently; (Few application scenarios)
  • Abstract association is used to replace multi-level inheritance and the inheritance relation between classes is transformed into dynamic object combination relation. (Used more, to avoid multi-layer inheritance type explosion problem)

Usage scenarios

  1. A system needs to add more flexibility between the abstract orange colors and the embodied personas that are built. Avoiding static inheritance between the two levels, the bridge pattern allows them to establish an association at the abstraction level.
  2. A class has two dimensions that vary independently, and both dimensions need to be extended.
  3. The bridge pattern can also be used for systems where inheritance is not desirable or where the number of system classes increases dramatically due to multi-level inheritance.

The advantages and disadvantages

Advantages: 1. Separation of abstraction and implementation. 2. Excellent ability to expand. 3. Implementation details are transparent to customers.

Disadvantages: The introduction of bridge mode will increase the difficulty of understanding and designing the system. Since the aggregation association relationship is established at the abstraction layer, developers are required to design and program for abstraction.

The specific implementation

For example, now we have a circle and a rectangle, which can abstract the shape parent class, and then they correspond to two subclasses:

abstract class Shape {
    abstract void show(a);
}

public class Circle extends Shape {
    @Override void show(a) { System.out.println("Circular"); }}public class Square extends Shape {
    @Override void show(a) { System.out.println("Rectangle"); }}Copy the code

If you add variations: colors, red and blue, combine with shapes to form the following four parent classes:

public class RedCircle extends Shape {
    @Override void show(a) { System.out.println("Red circle"); }}public class RedSquare extends Shape {
    @Override void show(a) { System.out.println("Red rectangle"); }}public class BlueCircle extends Shape {
    @Override void show(a) { System.out.println("Blue circle"); }}public class BlueSquare extends Shape {
    @Override void show(a) { System.out.println("Blue rectangle"); }}Copy the code

If the shape triangle and ellipse are added, then the number of subclasses becomes 4 * 2 = 8. If the color gold is added, then the number of subclasses becomes 4 * 3 = 12.

This problem can be solved by introducing the bridge pattern, where the two dimensions of change are clear: shape & color, which we understand as the abstract part and the latter as the implementation part, and bridge between them.

The implementation code is as follows:

// Color → Implementation section
public interface IColor {
    String draw(a);
}

// Red and blue → Implementation part concrete implementation
public class Red implements IColor {
    @Override public String draw(a) { return "Red"; }}public class Blue implements IColor {
    @Override
    public String draw(a) { return "Blue"; }}// Shape → Abstract part
abstract class Shape {
    // The shape holds the color reference, which is injected through the constructor, which is the bridging process
    protected IColor color;
    public Shape(IColor color) { this.color = color; }
    abstract void show(a);
}

// Circle, rectangle, abstract part extension
public class Circle extends Shape {
    public Circle(IColor color) { super(color); }
    @Override void show(a) { System.out.println(color.draw() + "Circular"); }}public class Square extends Shape {
    public Square(IColor color) { super(color); }
    @Override void show(a) { System.out.println(color.draw() + "Rectangle"); }}Copy the code

The output is as follows:

// Test case
public class CircleTest {
    public static void main(String[] args) {
        Shape redCircle = new Circle(new Red());
        Shape blueSquare = new Square(newBlue()); redCircle.show(); blueSquare.show(); }}Copy the code
Red circle blue rectangleCopy the code