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.