Bridge pattern of structural mode

definition:

Separate the abstract part from its implementation part so that they can change independently. It is an object structure mode, also known as handle and body mode or interface mode.

The bridge mode is similar to the multiple inheritance scheme, but the multiple inheritance scheme often violates the principle of single responsibility of class, and its reusability is relatively poor. The bridge mode is a better alternative than multiple inheritance.
The core of bridging pattern is decoupling abstraction and implementation.

Note: the abstraction here does not refer to the high-level concept of abstract class or interface, and the implementation is not inheritance or interface implementation. Abstract and realization actually refer to two independent dimensions. Among them, abstraction includes implementation. Therefore, the change of an abstract class may be caused by the change of multiple dimensions.

Main roles:

- Abstraction( Abstraction)Role: defines an abstract class and contains a reference to the implementation object.
- Extended abstraction( Refined  Abstraction)Role: it is a subclass of the abstract role, which implements the business methods in the parent class and calls the business methods in the abstract role through the composition relationship.
- Realization( Implementor)Role: defines the interface to implement the abstract role, which can be called by the extended abstract role.
- Concrete realization( Concrete Implementor)Role: give the specific implementation of the implementation role interface.

Main solution

When a class has two or more change dimensions, the use of bridging mode can decouple these change dimensions and stabilize the high-level code architecture.

advantage

Separation of abstraction and Implementation: This is the main feature of bridging mode and the main reason to avoid inheritance. Using the bridge mode, the abstraction and implementation are decoupled, so that the changes of the two will not affect the other party, and the scalability of the system is greatly enhanced.
Excellent scalability: the emergence of bridge mode is to solve the coupling of multiple independent changing dimensions, and its high-level module aggregation relationship has been determined (stable). Therefore, whether it is abstract change or implementation change, as long as it is extended, the high-level code can receive the extension without any change. High level code relies on abstraction and strictly follows the principle of dependency inversion.
Implementation details are transparent to customers: due to the bridge mode, a stable architecture (encapsulation) is built through aggregation relationship in the high-level module (abstraction layer). Therefore, customers only need to interact with high-level modules without paying attention to the details of abstraction and implementation.

shortcoming

Because the aggregation association relationship is based on the abstraction layer, the bridging mode requires developers to design and program for the abstraction, which will increase the difficulty of system understanding and design.

Usage scenario

  • A class has two (or more) independently changing dimensions, and both dimensions need to be extended;
  • Scenarios where inheritance is not desired or appropriate;
  • When a system needs to add more flexibility between the abstract and concrete roles of components. Avoid establishing static inheritance relationship between the two levels, and make them establish an association relationship in the abstract level through bridging mode.

example

[example] video player

A cross platform video player needs to be developed, which can play video files in various formats on different operating system platforms (such as Windows, Mac, Linux, etc.), and the common video formats include RMVB, AVI, WMV, etc. The player contains two dimensions and is suitable for using bridging mode.

Class diagram

Video file interface (implementing role)

/**
 * @author pzz
 * @date 2022/5/17
 * video file 
 * Realize role
 */
public interface VideoFile {
    //Decoding function
    public void decode(String fileName);
}

avi video file (specific implementation role)

/**
 * @author pzz
 * @date 2022/5/17
 * avi video file 
 * Specific implementation roles
 */
public class AviFile implements VideoFile{
    @Override
    public void decode(String fileName) {
        System.out.println("avi Video files:"+fileName);
    }
}

rmv video file (specific implementation role)

/**
 * @author pzz
 * @date 2022/5/17
 * rmv video file 
 * Specific implementation roles
 */
public class RmvbFile implements VideoFile{
    @Override
    public void decode(String fileName) {
        System.out.println("rmv Video files:"+fileName);
    }
}

Abstract operating system classes (Abstract roles)

/**
 * @author pzz
 * @date 2022/5/17
 * Abstract operating system classes
 * Abstract role
 */
public abstract class OpratingSystem {
    //Declare video object
    protected VideoFile videoFile;

    public OpratingSystem(VideoFile videoFile) {
        this.videoFile = videoFile;
    }

    public abstract void play(String fileName);
}

Mac operating system (extended abstract role)

/**
 * @author pzz
 * @date 2022/5/17
 * mac operating system
 * Extended abstract role
 */
public class Mac extends OpratingSystem{
    public Mac(VideoFile videoFile) {
        super(videoFile);
    }

    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}

Windows operating system (extended abstract role)

/**
 * @author pzz
 * @date 2022/5/17
 * Windows operating system
 * Extended abstract role
 */
public class Windows extends OpratingSystem{

    public Windows(VideoFile videoFile) {
        super(videoFile);
    }

    @Override
    public void play(String fileName) {
        videoFile.decode(fileName);
    }
}

Class test

/**
 * @author pzz
 * @date 2022/5/17
 * Class test
 */
public class Client {
    public static void main(String[] args) {
        //Create mac system object
        OpratingSystem system = new Mac(new AviFile());
        //Play video files using the operating system
        system.play("Charlotte's troubles");
    }
}

test result

Explanation:

Operating system and video files are two dimensions. When you need them, they can be expanded independently without affecting the original code.

Benefits:

  • The bridging mode improves the scalability of the system. If one of the two change dimensions is extended arbitrarily, there is no need to modify the original system.

    For example, if there is still a video file type wmv, we only need to define another class to implement the VideoFile interface, and other classes do not need to be changed.

  • Make details transparent to customers

Similarities and differences between adapter mode and bridge mode:

Common ground: both bridge and adapter work together.

Different points: different starting points.

  • Adapter: change the existing two interfaces to make them compatible.
  • Bridge mode: separate abstraction and implementation, so that their interfaces can be different. The purpose is to separate them.

So, if you get two existing modules and want them to work at the same time, you use the adapter.
If you don't have anything yet, but want to implement it separately, bridging is an option.

Difference between decoration mode and bridge mode:

Both models are designed to solve the problem of too many subclasses, but their incentives are different:

  • The bridging mode object itself has the trend of changing along multiple dimensions and is unstable. It should be used at the beginning of design.
  • Decoration mode is a mode that adds new functions to meet new requirements and does not affect other objects. It is used when extending.

end!

				When you think this is right, you should stick to it.

Tags: Java Design Pattern programming language

Posted by Loki on Mon, 16 May 2022 22:12:08 +0300