Introduction to design patterns 11 Bridging mode

Posted by turbocueca on Mon, 07 Mar 2022 03:10:33 +0100

The bridge pattern is simply to separate the abstract part from its implementation part, so that they can change independently.

In some compositions, if each class implements different services, Cartesian product may appear, and the use of bridge mode can easily decouple abstraction from implementation, so that they can change independently. How do we understand it? Suppose we have a task to pay the order, we can pay by Alipay and WeChat, and Alipay and WeChat pay face recognition and fingerprint recognition respectively. The payment method and verification method can correspond to each other. At this time, the choice produces Cartesian product:

Alipay + face, Alipay + fingerprint, WeChat + face, WeChat + fingerprint.

With the increase of payment methods and verification methods, we produce more Cartesian products. If we use strong correlation method to build code, it will cause a lot of dead code and increase the workload.

One solution to this problem is to use bridging mode. We abstract Alipay and WeChat into payment classes, and face and fingerprints are abstracted as verification methods. In the middle, a bridge is used to connect them. This is the basic realization of bridging mode. That is, when a class has two independently changing dimensions and both dimensions need to be extended, it will be more convenient for us to use the bridging mode.

=========================================================================

Let's simulate the above payment example:

When we use bridging, we will consider the parts on both sides of the bridge. We can abstract two categories: one is the method of payment and the other is the method of verification. Then we connect the two parts. Every payment method needs verification, so we abstract the verification mode into an interface:

Interface of verification mode (bridge interface):

package BridgePattern;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName PayMode.java
 * @Description Verification mode interface
 * @createTime 2022 09:04:00, March 7
 */
public interface  PayMode {

    /**
     * Permission verification
     * @param uid User id
     * @return Is the verification successful
     */
    boolean security(String uid);

}

Then extract the payment method into an abstract class:

package BridgePattern;

import java.math.BigDecimal;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName Payment.java
 * @Description Payment method abstract class
 * @createTime 2022 09:01:00, March 7
 */
public abstract class Payment {

    /**
     * Bridge interface
     */
    protected PayMode payMode;

    public Payment(PayMode payMode){
        this.payMode = payMode;
    }

    /**
     * Transfer interface
     * @param uId User ID
     * @param tradeId Transaction ID
     * @param amount Total payment
     * @return Success information
     */
    public abstract String transfer(String uId, String tradeId, BigDecimal amount);


}

Specific realization of payment method:

Alipay:

package BridgePattern.payment;

import BridgePattern.PayMode;
import BridgePattern.Payment;

import java.math.BigDecimal;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName Alipay.java
 * @Description Alipay
 * @createTime 2022 09:12:00, March 7
 */
public class Alipay extends Payment {
    public Alipay(PayMode payMode) {
        super(payMode);
    }

    @Override
    public String transfer(String uId, String tradeId, BigDecimal amount) {
        //Permission verification
        boolean security = payMode.security(uId);

        System.out.println("Alipay transfer:");
        System.out.println("Confirm the account number of the opposite party:"+tradeId);
        if (!security){
            return "Permission verification failed";
        }else {
            return "Alipay transfer successful, payment amount:"+amount+"element";
        }
    }
}

Wechat payment:

package BridgePattern.payment;

import BridgePattern.PayMode;
import BridgePattern.Payment;

import java.math.BigDecimal;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName WechatPay.java
 * @Description Wechat payment
 * @createTime 2022 09:08:00, March 7
 */
public class WechatPay extends Payment {

    @Override
    public String transfer(String uId, String tradeId, BigDecimal amount) {
        //Permission verification
        boolean security = payMode.security(uId);

        System.out.println("Wechat transfer:");
        System.out.println("Confirm the account number of the opposite party:"+tradeId);

        if (!security){
            return "Permission verification failed";
        }else {
            return "Wechat transfer succeeded, payment amount:"+amount+"element";
        }
    }

    public WechatPay(PayMode payMode){
        super(payMode);
    }

}

Specific implementation of verification interface:

Facial recognition verification:

package BridgePattern.PayModes;

import BridgePattern.PayMode;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName FacialRecognition.java
 * @Description Face recognition
 * @createTime 2022 09:16:00, March 7
 */
public class FacialRecognition implements PayMode {

    @Override
    public boolean security(String uid) {
        System.out.println("Face recognition call");
        return "00001".equals(uid);
    }

}

Fingerprint identification verification:

package BridgePattern.PayModes;

import BridgePattern.PayMode;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName fingerPrintIdentification.java
 * @Description fingerprint identification
 * @createTime 2022 09:20:00, March 7
 */
public class FingerPrintIdentification implements PayMode {

    @Override
    public boolean security(String uid) {
        System.out.println("Fingerprint identification call");
        return "00001".equals(uid);
    }
}

Test:

package BridgePattern;

import BridgePattern.PayModes.FingerPrintIdentification;
import BridgePattern.payment.WechatPay;

import java.math.BigDecimal;

/**
 * @author Zeyu Wan
 * @version 1.0.0
 * @ClassName BridgePatternTest.java
 * @Description Bridge mode test class
 * @createTime 2022 09:22:00, March 7
 */
public class BridgePatternTest {
    public static void main(String[] args) {
        Payment pay = new WechatPay(new FingerPrintIdentification());
        System.out.println(pay.transfer("00001","12345",new BigDecimal(99999)));
    }
}

It can be seen that when using the payment interface, users do not need to pay attention to the internal implementation, but only pay attention to the payment method and payment verification method. And the interface also has good scalability, such as adding payment methods and adding authentication methods, which can be added to our methods through simple inheritance and implementation, and then called by users.

advantage:

  • In many cases, the bridge mode can replace the multi-layer inheritance scheme. The multi-layer inheritance scheme violates the "single responsibility principle", has poor reusability, and has a large number of classes. The bridge mode is a better solution than the multi-layer inheritance scheme, which greatly reduces the number of subclasses.
  • The bridging mode improves the scalability of the system. Expanding one of the two change dimensions without modifying the original system conforms to the "opening and closing principle".

Disadvantages:

  • The use of bridging mode will increase the difficulty of system understanding and design. Because the correlation is based on the abstract layer, developers are required to design and program for the abstract layer from the beginning.

Topics: Design Pattern