Hand design mode - appearance mode

1, Appearance mode introduction

1.1 definitions

Facade pattern:
The external communication with a subsystem must be carried out through a unified appearance object to provide a consistent interface for a group of interfaces in the subsystem. The appearance mode defines a high-level interface, which makes the subsystem easier to use. Appearance mode, also known as facade mode, is an object structure mode.
System application performance:
Appearance mode is also called facade mode, which mainly solves the problem of reducing the complex logical combination of the caller's interface. In this way, the caller and the actual interface provider provide an intermediate layer for packaging logic to provide API interfaces. Sometimes, the appearance pattern is also used in the middleware layer to package the common and complex logic in the service, so that the user can only care about business development.

1.2 schematic diagram:

1.3 structure of mode

  • The Facade mode contains the following main roles.
  • Facade role: provide a common interface for multiple subsystems.
  • Sub System role: realize some functions of the system, and customers can access it through appearance role.
  • Client role: access the functions of each subsystem through one appearance role.

1.4 code demonstration

Appearance character object:

/**
 * Description: It provides an appearance interface. Externally, it provides an interface that is easy to be accessed by the client. Internally, it can access all functions in the subsystem.
 * <br/>
 * Facade
 *
 * @author laiql
 * @date 2021/10/26 17:05
 */
public class Facade {
	
	//Delegate dependent subsystem object
    private SubSystemOne subSystemOne;
    private SubSystemTwo subSystemTwo;

    public Facade() {
        subSystemOne = new SubSystemOne();
        subSystemTwo = new SubSystemTwo();
    }
    //Unified call subsystem
    public void method() {
        System.out.println("External interface implementation");
        subSystemOne.method();
        subSystemTwo.method();
    }
}

Create 1 subsystem class:

/**
 * Description: Subsystem role 1
 * The subsystem can be one or more modules in the whole system. Each module is composed of several classes, which may have complex relationships with each other.
 * <br/>
 * SubSystemOne
 *
 * @author laiql
 * @date 2021/10/26 17:05
 */
public class SubSystemOne {
    public void method(){
        System.out.println("SubSystemOne.method");
    }
}

Create 2 subsystem classes:

/**
 * Description: Subsystem role 2
 * The subsystem can be one or more modules in the whole system. Each module is composed of several classes, which may have complex relationships with each other.
 * <br/>
 * SubSystemTwo
 *
 * @author laiql
 * @date 2021/10/26 17:05
 */
public class SubSystemTwo {
    public void method(){
        System.out.println("SubSystemTwo.method");
    }
}

Create client authentication:

/**
 * Description: Client call role
 * <br/>
 * Client
 *
 * @author laiql
 * @date 2021/10/26 17:09
 */
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.method();
    }
}

Expected result of use case:

Connected to the target VM, address: '127.0.0.1:61790', transport: 'socket'
External interface implementation
SubSystemOne.method
SubSystemTwo.method
Disconnected from the target VM, address: '127.0.0.1:61790', transport: 'socket'

2, Application scenario of adaptation mode

2.1 scenario overview

In daily life, we will encounter such a situation, such as combined payment. When constructing combined payment, we can use appearance mode to realize it. Another additional advantage of using appearance mode is that we can selectively expose methods. The methods defined in a module can be divided into two parts, one for external use of the subsystem and the other for mutual calls between modules within the subsystem. With the PayFacade class, the methods used to call each other between modules within the subsystem need not be exposed to the outside of the subsystem.

2.2 example overview

Background: when we pay, we will encounter multiple modes of combination payment, such as Alipay and WeChat payment.
Conflict: when our Alipay balance is not enough, we can combine payment with WeChat and so on. At this time, we can provide a unified package when we provide external structure.

2.3 code practice

Define Alipay payment components:

/**
 * Description: Alipay payment component
 * <br/>
 * ZFBPayComponent
 *
 * @author laiql
 * @date 2021/10/26 17:24
 */
@Data
@AllArgsConstructor
public class ZFBPayComponent {
    private String userId;
    private BigDecimal money;
    /**
     * Payment method
     */
    public void pay() {
        System.out.println("user ID: " + userId + " Alipay payment:" + money + "element");
    }
}

Define wechat payment components:

/**
 * Description: Wechat payment component
 * <br/>
 * WxPayComponent
 *
 * @author laiql
 * @date 2021/10/26 17:24
 */
@Data
@AllArgsConstructor
public class WxPayComponent {

    private String userId;
    private BigDecimal money;

    /**
     * Payment method
     */
    public void pay() {
        System.out.println("user ID: " + userId + " Wechat payment:" + money + "element");
    }
}

Define unified payment facade:

/**
 * Description: Combined payment facade
 * <br/>
 * PayFacade
 *
 * @author laiql
 * @date 2021/10/26 17:27
 */
public class PayFacade {

    private WxPayComponent wxPayComponent;
    private ZFBPayComponent zfbPayComponent;

    public PayFacade(WxPayComponent wxPayComponent, ZFBPayComponent zfbPayComponent) {
        this.wxPayComponent = wxPayComponent;
        this.zfbPayComponent = zfbPayComponent;
    }
    /**
     * Unified combined payment facade
     */
    public void unifiedPayment() {
        this.zfbPayComponent.pay();
        this.wxPayComponent.pay();
        System.out.println("total:" + new BigDecimal("0").add(wxPayComponent.getMoney()).add(zfbPayComponent.getMoney()));
    }
}

Test case:

/**
 * Description: Appearance pattern test case
 * <br/>
 * FacadeTest
 *
 * @author laiql
 * @date 2021/10/22 9:59 afternoon
 */
public class FacadeTest {
    @Test
    public void facadeTest() {
        PayFacade payFacade = new PayFacade(new WxPayComponent("10001", new BigDecimal(10)),
                new ZFBPayComponent("10001", new BigDecimal(10)));
        payFacade.unifiedPayment();
    }
}

Expected results of test cases:

Connected to the target VM, address: '127.0.0.1:60612', transport: 'socket'
user ID: 10001 Alipay payment:10 element
 user ID: 10001 Wechat payment:10 element
 Total: 20
Disconnected from the target VM, address: '127.0.0.1:60612', transport: 'socket'
Process finished with exit code 0

3, Advantages and disadvantages

3.1 advantages

● loose coupling

The appearance mode looses the coupling relationship between the client and the subsystem, making it easier for the modules inside the subsystem to expand and maintain.

● easy to use

Appearance mode makes the subsystem easier to use. The client no longer needs to understand the implementation inside the subsystem, nor does it need to interact with many modules inside the subsystem. It only needs to interact with appearance classes.

● better division of access levels

The rational use of Facade can help us better divide the access level. Some methods are used outside the system, while others are used inside the system. The functions that need to be exposed to the outside are concentrated in the appearance, which is not only convenient for the client to use, but also hides the internal details.

3.2 disadvantages

  • Adding a new subsystem without introducing an abstract appearance class may require modifying the appearance class or the source code of the client, which violates the "opening and closing principle"
  • It can not well restrict customers' use of subsystem classes. If too many restrictions are made on customers' access to subsystem classes, it will reduce variability and flexibility.

4, Summary

  • The core of the implementation of the appearance pattern is that the appearance class saves the references of each subsystem, and a unified appearance class wraps multiple subsystem classes. However, the client only needs to reference this appearance class, and then the appearance class calls the methods in each subsystem.
  • This implementation is very similar to the adapter pattern, but the difference between the appearance pattern and the adapter pattern is that the adapter pattern wraps an object to change its interface, while the appearance wraps a group of objects "To simplify their interfaces. Their intentions are different. The adapter is to convert interfaces into different interfaces, and the appearance mode is to provide a unified interface to simplify the interface.
  • Most of the time, it is not that the design pattern is useless, but that the lack of programming experience has made it hard to control even learning the design pattern. After all, these knowledge are distilled from some practical operations.

Code address

Tags: Design Pattern

Posted on Tue, 26 Oct 2021 05:30:01 -0400 by hafez