JAVA Design Patterns: Facade Pattern
Classification Programming Technology
Hospital Example
Modern software systems are relatively complex. A common method for designers to handle complex systems is to "divide and conquer," dividing a system into several smaller subsystems. Taking a hospital as a subsystem, according to departmental functions, this system can be divided into registration, outpatient, pricing, laboratory testing, billing, medication dispensing, etc. Patients seeking medical treatment need to deal with these departments, just as a subsystem client needs to interact with various classes of a subsystem, which is not an easy task.
Facade Pattern Structure
The Facade pattern does not have a generalized class diagram description. The best way to describe it is actually to illustrate it with an example.
Facade Role: The client can call the methods of this role. This role is aware of the functions and responsibilities of the related (one or more) subsystems. Under normal circumstances, this role will delegate all requests from the client to the corresponding subsystem.
Subsystem (SubSystem) Role: There can be one or more subsystems at the same time. Each subsystem is not a single class but a collection of classes (for example, the above subsystem is composed of three classes: ModuleA, ModuleB, and ModuleC). Each subsystem can be directly called by the client or by the Facade role. The subsystem is not aware of the existence of the Facade, and for the subsystem, the Facade is just another client.
Source Code
Classes in the Subsystem Role:
public class ModuleA {
// Example method
public void testA(){
System.out.println("Calling testA method in ModuleA");
}
}
public class ModuleB {
// Example method
public void testB(){
System.out.println("Calling testB method in ModuleB");
}
}
public class ModuleC {
// Example method
public void testC(){
System.out.println("Calling testC method in ModuleC");
}
}
Facade Role Class:
public class Facade {
// Example method, fulfilling the client's required functionality
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 essentially the facade interface for modules A, B, and C. With this Facade class, the client does not need to directly call the A, B, and C modules in the subsystem, nor does it need to know the internal implementation details of the system, or even the existence of modules A, B, and C. The client only needs to interact with the Facade class, thereby better achieving decoupling between the client and the A, B, and C modules in the subsystem, making it easier for the client to use the system.
Implementation of the Facade Pattern
Using the Facade pattern also has the added benefit of selectively exposing methods. The methods defined in a module can be divided into two parts: one part is for external use of the subsystem, and the other part is for internal calls between modules within the subsystem. With the Facade class, the methods used for internal calls between modules within the subsystem do not need to be exposed to the outside of the subsystem.
For example, define the following A, B, and C modules.
public class ModuleA {
/**
* Method provided for external use of the subsystem
*/
public void a1(){};
/**
* Method used for internal calls between modules within the subsystem
*/
private void a2(){};
private void a3(){};
}
public class ModuleB {
/**
* Method provided for external use of the subsystem
*/
public void b1(){};
/**
* Method used for internal calls between modules within the subsystem
*/
private void b2(){};
private void b3(){};
}
public class ModuleC {
/**
* Method provided for external use of the subsystem
*/
public void c1(){};
/**
* Method used for internal calls between modules within the subsystem
*/
private void c2(){};
private void c3(){};
}
```java public class ModuleFacade {
ModuleA a = new ModuleA();
ModuleB b = new ModuleB();
ModuleC c