Category: Structural design patterns

Purpose: Divide abstraction and implementation into two dimensionally divided parts (usually two types of interfaces) so that both parts can iterate (change) independently and prevent the number of classes from exploding

1drv.ms/u/s! AquRvPz…

A typical scenario

When the number of abstractions is large and the number of abstractions may increase dramatically (for example, 2-3 classes for a single feature), the bridge pattern should be considered

For example, there are multiple remote control scenes of abstract universal TV, and there are multiple remote control scenes (each scene has different functions), and there are multiple types of cars (trucks, buses, cars, etc.) to adapt to a variety of TV types. The production process of each type of car is not the same

Here is an example of the universal remote control scenario. The scenarios are as follows:

  1. Basic remote control scenario: Power on and power off
  2. TV scene: Select the TV station and turn it on and off
  3. Movie scene: play, pause, switch off, etc

As you can see there is a hierarchy to the scene, for example the TV scene covers the basic on-off airport scene

At present, the TV types for example are as follows:

  1. SONY TV
  2. Samsung TV

You can see that there’s probably more adaptation for this TV genre

Abstract the scene

Abstract classes are used here to abstract the remote control scene

1. Basic remote control scenario

abstract public class CommonScenes {
    abstract public void turnOn(a);

    abstract public void tureOff(a);
}
Copy the code

2. Watch TV scenes

abstract public class TvScenes extends CommonScenes {
    abstract void setChannel(a);
}
Copy the code

3. Watch movie scenes

abstract public class MovieScenes extends CommonScenes {
    abstract void pause(a);

    abstract void play(a);
}
Copy the code

Realization of different types of TV scene operation corresponding to the specific code

For example, there are n scenes and M TV types, and each TV type implements N scenes once, then the number of implementations will be N *m. With the increase of N or M, the number of concrete implementations will increase sharply, as shown below:

implementation class
Samsung basic remote control scene implementation SamsungTvCommonScenes.java
Samsung movie scene implementation SamsungTvMovieScenes.java
Samsung watch TV scene implementation SamsungTvTvScenes.java
SONY basic remote control scene implementation SonyTvCommonScenes.java
SONY Movie scene implementation SonyTvMovieScenes.java
SONY watch TV scene implementation SonyTvTvScenes.java

Here is an example of Samsung watching TV scene for reference as follows:

public class SamsungTvTvScenes extends TvScenes {
    @Override
    void setChannel(a) {
        // Use the Samsung TV SDK to switch between Samsung TV stations
        System.out.println("samsung tv set channel");
    }

    @Override
    public void turnOn(a) {
        // Use the Samsung TV SDK to boot
        System.out.println("samsung tv turn on");
    }

    @Override
    public void tureOff(a) {
        // Use the Samsung TV SDK to shut down
        System.out.println("samsung tv turn off"); }}Copy the code

The code hierarchy reference is as follows:

As you can see, the number of implementations increases dramatically as the scenario/TV type increases, which is not conducive to scaling, so you can use the bridge design pattern

Pattern implementation

The above two dimensions of scene and TV type are divided into two abstractions: scene abstraction and TV abstraction. The responsibilities are as follows:

  1. TV abstraction: only responsible for abstracting the TV and realizing the functions in the abstraction
  2. Scene abstraction: only responsible for the abstract scene, control the specific logic of the TV to the TV abstraction

The TV abstract interface is as follows

public interface Television {
    void turnOn(a);

    void tureOff(a);

    void setChannel(a);
}
Copy the code

Different TV types can achieve this TV interface, such as Samsung TV reference as follows:

public class SamsungTelevision implements Television {
    @Override
    public void turnOn(a) {
        System.out.println("samsung tv turn on");
    }

    @Override
    public void tureOff(a) {
        System.out.println("samsung tv turn off");
    }

    @Override
    public void setChannel(a) {
        System.out.println("samsung tv set channel"); }}Copy the code

In this way, the scene only needs to hold references to different TV types, rather than abstracting them separately, as shown below

public class CommonScenes {
    private Television television; // Hold a reference to the TV

    public CommonScenes(Television television) {
        this.television = television;
    }

    public void turnOn(a) {
        television.turnOn();
    }

    public void tureOff(a) { television.tureOff(); }}Copy the code

UML

Why is bridge mode better

The two dimensions can be independently expanded, such as adding a new scene or a new TV type, which will not cause a sudden increase in the number of classes. The two dimensions of scene and TV can be combined to achieve a complete scene, such as Samsung TV watching movies scene combination code is as follows:

Television samsumngTelevision = new SamsungTelevision();
MovieScenes movieScenes = new MovieScenes(samsumngTelevision);/ /
    
movieScenes.pause();
movieScenes.play();
Copy the code

A couple of points to note

Through the bridge, it can be divided into parts that can be independently expanded according to dimensions, and then form a complete use scenario through combination

The resources

  1. www.geeksforgeeks.org/bridge-desi…