Design Patterns Series Articles
Design Patterns (1): Creational Singleton Patterns
Design Patterns (2, 3): Creational Factory Methods and Abstract Factory Patterns
Design Patterns (4): Creational Prototype Patterns
Design Pattern (5): Creational Builder Pattern
Design Pattern (6): Structural Agent Pattern
Design Pattern (7): Structural Adapter Pattern
Design Pattern (8): Structural Decorator Pattern
Design Pattern (9): Structural Bridge Pattern
Design Patterns (10): Structural Appearance Patterns
Table of contents
1. Classification of Design Patterns
- Creational patterns
- Used to describe "how to create objects", its main feature is "separation of object creation and use"
- Provides singletons, prototypes, factory methods, abstract factories, and builders
5 种创建型模式
- structural pattern
- Used to describe how to organize classes or objects into larger structures in a certain layout
- Proxy, Adapter, Bridge, Decorator, Facade, Flyweight, Composition are provided
7 种结构型模式
- behavioral model
- Used to describe how classes or objects cooperate with each other to complete tasks that a single object cannot do alone, and how to assign responsibilities
- Provides template methods, policies, commands, chain of responsibility, state, observers, mediators, iterators, visitors, mementos, interpreters
11 种行为型模式
2. Appearance mode
1 Overview
definition
- aka
门面模式
- is a method that provides a consistent interface for multiple complex subsystems
- patterns that make these subsystems more accessible
- This mode has a unified interface to the outside world
- The external application does not need to care about the specific details of the internal subsystem
- This will greatly reduce the complexity of the application and improve the maintainability of the program
2. Structure
The Facade pattern has the following main roles:
- Facade role: provide a common interface for multiple subsystems
- Subsystem (Sub System) role: implements some functions of the system, and customers can access it through the appearance role
3. Realize
Smart Appliance Control
- Living alone at home: every time you need to turn on the lights, turn on the TV, and turn on the air conditioner
- Turn off the lights, turn off the TV, and turn off the air conditioner when sleeping; it is more troublesome to operate
- Bought a smart speaker, you can directly control the opening and closing of these smart home appliances through voice
The class diagram is as follows:
code show as below:
- Home appliances
//灯类
public class Light {
public void on() {
System.out.println("打开了灯....");
}
public void off() {
System.out.println("关闭了灯....");
}
}
//电视类
public class TV {
public void on() {
System.out.println("打开了电视....");
}
public void off() {
System.out.println("关闭了电视....");
}
}
//控制类
public class AirCondition {
public void on() {
System.out.println("打开了空调....");
}
public void off() {
System.out.println("关闭了空调....");
}
}
- Appearance class, the user mainly interacts with this class of objects
// 智能音箱
public class SmartAppliancesFacade {
//聚合电灯对象,电视机对象,空调对象
private Light light;
private TV tv;
private AirCondition airCondition;
public SmartAppliancesFacade() {
light = new Light();
tv = new TV();
airCondition = new AirCondition();
}
//通过语言控制
public void say(String message) {
if(message.contains("打开")) {
on();
} else if(message.contains("关闭")) {
off();
} else {
System.out.println("我还听不懂你说的!!!");
}
}
//一键打开功能
private void on() {
light.on();
tv.on();
airCondition.on();
}
//一键关闭功能
private void off() {
light.off();
tv.off();
airCondition.off();
}
}
- client test class
public class Client {
public static void main(String[] args) {
//创建外观对象
SmartAppliancesFacade facade = new SmartAppliancesFacade();
//客户端直接与外观对象进行交互
facade.say("打开家电");
System.out.println("==================");
facade.say("关闭家电");
}
}
结果:
打开电灯。。。。
打开电视机。。。。
打开空调。。。。
==================
关闭电灯。。。。
关闭电视机。。。。
关闭空调。。。。
benefit
- Reduce the coupling between the subsystem and the client, so that the change of the subsystem will not affect the client class that calls it
- Shields subsystem components from clients, reduces the number of objects handled by clients, and makes the subsystem easier to use
shortcoming
- It does not conform to the principle of opening and closing, and it is very troublesome to modify
4. Usage scenarios
- When building a hierarchical system, using the facade pattern to define the entry point for each layer in the subsystem can simplify the dependencies between subsystems
- When a complex system has many subsystems, the appearance mode can design a simple interface for the system to be accessed by the outside world.
- When there is a strong connection between the client and multiple subsystems, the introduction of the facade mode can separate them, thereby improving the independence and portability of the subsystems
5. Source code analysis
- When using tomcat as the web container, when receiving the request sent by the browser, tomcat will encapsulate the request information into a ServletRequest object
- ServletRequest is an interface, it also has a sub-interface HttpServletRequest
- The request object must be a sub-implementation class object of the HttpServletRequest object. Which class object is it?
- By outputting the request object, we will find that it is an object of a class called RequestFacade
- The RequestFacade class uses the appearance pattern
Structure diagram:
RequestFacade class:
public class RequestFacade implements HttpServletRequest {
protected Request request = null;
public RequestFacade(Request request) {
this.request = request;
}
...
public Object getAttribute(String name) {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
} else {
return this.request.getAttribute(name);
}
}
public Enumeration<String> getAttributeNames() {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
} else {
return Globals.IS_SECURITY_ENABLED ? (Enumeration)AccessController.doPrivileged(new GetAttributePrivilegedAction()) : this.request.getAttributeNames();
}
}
public String getCharacterEncoding() {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
} else {
return Globals.IS_SECURITY_ENABLED ? (String)AccessController.doPrivileged(new GetCharacterEncodingPrivilegedAction()) : this.request.getCharacterEncoding();
}
}
...
}
Why use facade mode here?
- Define the RequestFacade class to implement ServletRequest respectively
- At the same time, the private member variable Request is defined, and the implementation of the method calls the implementation of Request
- Convert RequestFacade to ServletRequest and pass it to the service method of servlet
- In this way, even if it is converted to RequestFacade in the servlet,
不能访问私有成员变量
the methods in the object - It not only uses Request, but also prevents its methods from being unreasonably accessed