Examples of hospitals
Modern software systems are more complex. A common way for designers to deal with complex systems is to "divide and rule", and divide a system into several smaller subsystems. If the hospital is regarded as a subsystem, according to the functions of the Department, this system can be divided into registration, outpatient service, pricing, testing, charging, taking medicine, etc. It is not easy for patients to deal with these departments, just as the client of a subsystem deals with various classes of a subsystem.
First, the patient must be registered first, and then outpatient. If the doctor asks for a test, the patient must first set the price and then pay the fee before he can go to the test department for a test. Return to the clinic after the test.
The above figure describes the experience of patients in the hospital, and the box in the figure represents the hospital.
The way to solve this inconvenience is to introduce the facade mode. The hospital can set up a position for the receptionist, who is responsible for registration, pricing, payment, taking medicine, etc. This receptionist is the embodiment of the facade mode. Patients only contact the receptionist, who deals with various departments.
Structure of facade mode
The facade pattern does not have a general class diagram description, and the best description method is actually illustrated by an example.
Because the structure diagram of facade pattern is too abstract, it is a little more specific. Assuming that there are three modules in the subsystem, namely ModuleA, ModuleB and ModuleC, which have an example method respectively, the overall structure diagram of the example is as follows:
In this object diagram, there are two roles:
● facade role: the client can call the method of this role. This role is aware of the functions and responsibilities of the relevant subsystem (s). Under normal circumstances, this role will delegate all requests sent from the client to the corresponding subsystem.
● subsystem role: there can be one or more subsystems at the same time. Each subsystem is not a separate class, but a collection of classes (for example, the subsystem above is composed of ModuleA, ModuleB and ModuleC). Each subsystem can be called directly by the client or by the facade role. The subsystem does not know the existence of the facade. For the subsystem, the facade is just another client.
source code
Classes in subsystem roles:
public class ModuleA { //Schematic method public void testA(){ System.out.println("call ModuleA Medium testA method"); } }
public class ModuleB { //Schematic method public void testB(){ System.out.println("call ModuleB Medium testB method"); } }
public class ModuleC { //Schematic method public void testC(){ System.out.println("call ModuleC Medium testC method"); } }
Facade role class:
public class Facade { //Schematic method to meet the functions required by the client public void test(){ ModuleA a = new ModuleA(); a.testA(); ModuleB b = new ModuleB(); b.testB(); ModuleC c = new ModuleC(); c.testC(); } }
Client role class:
public class Client { public static void main(String[] args) { Facade facade = new Facade(); facade.test(); } }
The Facade class is actually equivalent to the appearance interface of modules A, B and C. with this Facade class, the client does not need to call modules A, B and C in the subsystem, nor do they need to know the implementation details inside the system, or even the existence of modules A, B and C. The client only needs to interact with the Facade class, So as to better realize the decoupling of A, B and C modules in the client and subsystem, and make it easier for the client to use the system.
Realization of facade mode
Another added benefit of using Facade patterns is the ability to selectively expose methods. The methods defined in a module can be divided into two parts. One part is used outside the subsystem and the other part is used when the modules inside the subsystem call each other. With the Facade class, the methods used to call each other between modules within the subsystem need not be exposed to the outside of the subsystem.
For example, modules A, B and C are defined as follows.
public class Module { /** * Methods provided for external use of the subsystem */ public void a1(){}; /** * The method used when calling each other between modules within the subsystem */ private void a2(){}; private void a3(){}; }
public class ModuleB { /** * Methods provided for external use of the subsystem */ public void b1(){}; /** * The method used when calling each other between modules within the subsystem */ private void b2(){}; private void b3(){}; }
public class ModuleC { /** * Methods provided for external use of the subsystem */ public void c1(){}; /** * The method used when calling each other between modules within the subsystem */ private void c2(){}; private void c3(){}; }
public class ModuleFacade { ModuleA a = new ModuleA(); ModuleB b = new ModuleB(); ModuleC c = new ModuleC(); /** * The following are the methods provided by modules A, B and C to the outside of the subsystem */ public void a1(){ a.a1(); } public void b1(){ b.b1(); } public void c1(){ c.c1(); } }
Defining a moduleface class in this way can effectively shield the internal details, so as to prevent the client from finding some methods that it does not need to know when calling the Module class. For example, a2() and a3() methods do not need to be known by the client, otherwise they will not only expose the internal details, but also confuse the client. A3. What else can he do with a2() method? In fact, a2() and a3() methods interact between internal modules and are not external to the subsystem, so don't let the client know at all.
A system can have several facade classes
In facade mode, only one facade class is usually required, and this facade class has only one instance, in other words, it is a singleton class. Of course, this does not mean that there is only one facade class in the whole system, but only one facade class for each subsystem. In other words, if a system has several subsystems, each subsystem has a facade class, and the whole system can have several facade classes.
Add new behaviors to subsystems
Beginners often think that new behaviors can be added to the subsystem by inheriting a facade class, which is wrong. The purpose of facade mode is to provide a centralized and simplified communication channel for the subsystem, rather than adding new behaviors to the subsystem. For example, the receptionist in the hospital is not a medical staff, and the receptionist cannot provide medical services for patients.
Advantage facade mode
Advantages of facade mode:
● loose coupling
The facade 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
Facade 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 facade classes.
● better division of access levels
The rational use of Facade can help us better divide the level of access. 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 Facade, which is not only convenient for the client to use, but also hides the internal details.