This is the 16th day of my participation in the August More Text Challenge


1. Simplify access to complex subsystems

I still remember that in 2019, I developed a “talent allowance application system” for government departments, with the purpose of helping local cities attract talents and recruit talents. Local cities will be divided into several categories of talent, different categories of talent enjoy the allowance is not the same, for example, “master” and “doctoral” hand allowance is far from the same, if it is won a national award of talent is not allowed, will be directly allocated to the house. Of course, it is not easy to get the corresponding allowance. The premise conditions of different allowances are different, and the business is very complicated. In any case, all benefits are subject to the same two preconditions: 1. Local contributions to social security, 2. No criminal record. If it is a house allocation, another condition will be added, that is, I and my spouse have no house under their name. Therefore, in order to develop this system, I need to connect with the Social Security Bureau, the Ministry of Public Security and the Ministry of Housing and Urban-Rural Development, and use their interfaces to obtain personal data, so as to judge whether an individual meets the conditions for receiving subsidies.

We use code to describe this process, the class diagram design is very simple, as follows:The client needs to access three system interfaces to determine whether an individual is eligible for an allowance.

Three subsystem code abbreviations:

public class SheBaoSystem {

	public void getSBInfo(a) {
		System.out.println("Check social security, get personal social security information..."); }}public class ZhuJianSystem {

	public void getZJInfo(a) {
		System.out.println("Check with the Ministry of Housing and Urban-Rural Development to obtain personal housing information..."); }}public class GongAnSystem {

	public void getGAInfo(a) {
		System.out.println("Inquire the Ministry of Public Security, obtain personal criminal record information..."); }}Copy the code

The client calls like this:

public class Client {
	public static void main(String[] args) {
		SheBaoSystem sheBaoSystem = new SheBaoSystem();
		ZhuJianSystem zhuJianSystem = new ZhuJianSystem();
		GongAnSystem gongAnSystem = newGongAnSystem(); sheBaoSystem.getSBInfo(); zhuJianSystem.getZJInfo(); gongAnSystem.getGAInfo(); }} Output: query social security, obtain personal social security information... Check the Ministry of Housing and Urban-Rural Development for personal housing information... Inquire Ministry of Public Security, obtain personal criminal record information...Copy the code

The client can obtain personal social security information, housing information, criminal records and other data, based on these data to determine whether the individual is eligible for receiving conditions, done.

But soon, when my colleague was developing another function, he also needed to query these data, but he didn’t want to know how I interfaced with the third party subsystem. He asked me if I could provide a unified interface, so he could get these data with a simple call.

My answer is: sure, LET me write you a simple appearance class. The optimized class diagram design is as follows:

The subsystem class code remains the same, encapsulating a Facade class to simplify client calls to complex third-party systems.

/ / class appearance
public class Facade {
	private SheBaoSystem sheBaoSystem = new SheBaoSystem();
	private ZhuJianSystem zhuJianSystem = new ZhuJianSystem();
	private GongAnSystem gongAnSystem = new GongAnSystem();

	// Get social security information
	public void getSBInfo(a){
		this.sheBaoSystem.getSBInfo();
	}

	// Get housing information
	public void getZJInfo(a){
		this.zhuJianSystem.getZJInfo();
	}

	// Get the criminal record
	public void getGAInfo(a){
		this.gongAnSystem.getGAInfo(); }}Copy the code

The client calls like this:

public class Client {
	public static void main(String[] args) {
		Facade facade = newFacade(); facade.getSBInfo(); facade.getZJInfo(); facade.getGAInfo(); }}Copy the code

The results don’t change, and the client calls become very simple. Now I can just provide the Facade class to a colleague and it can just call the Facade class to get the data without knowing how I asked a third-party system to get the data, which is a truly “highly cohesive” implementation.

Simple, this is appearance mode!

2. Definition of appearance mode

It is required that communication between the outside and the inside of a subsystem must be carried out through a unified object. Facade mode provides a high-level interface that makes subsystems easier to use.

Appearance pattern generic class diagram

  • Facade: The Facade class, which is also invoked by the client, understands the functionality of all subsystems, has no logic of its own, and simply forwards requests to the corresponding subsystem for execution.
  • System* : Subsystem classes, the people who do the real work. Subsystems don’t know about the appearance classes.

The facade pattern is very simple and focuses on the “unified object”, no matter how complex the subsystem is, it always provides a simple interface for the client to call.

3. Pros and cons of appearance mode

advantages

  1. Loose coupling reduces the client’s dependence on the subsystem and only relies on the facade class, simplifying the use of the client.
  2. The lower-level implementation is shielded from higher-level modules, and business changes to subsystems are transparent to clients.
  3. Increased flexibility, no matter how the subsystem changes, as long as it doesn’t affect the facade classes.
  4. More security, the appearance class is the only access to the subsystem, for do not want to expose the interface, the appearance class is not open.

The downside is that the facade class can become very complex, becoming the only point of access to the subsystem, and the exception of the facade class is dead. And once the subsystem changes affect the facade class, the facade class has to be modified, which violates the “open closed principle”.

4. To summarize

If you want to provide a simple interface for external access to a complex module or subsystem, you can consider using facade mode. The facade also prevents low-level developers from extending their risks by preventing newcomers from directly calling the core modules of the system and providing only a facade class for their operations. Using appearance model, one thing is for developers often ignore, is “it is forbidden to write any logic in the appearance of class”, the appearance of class should only be responsible for forwarding the request, once the business logic, means that the subsystem must rely on appearance class can be accessed, rely on is as a result, it is design flaws, not only violated the “single responsibility”, also damage the encapsulation of the system.