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
Design Patterns (11): Structural Combination Patterns
Design Pattern (12): Structural Flyweight Pattern
Design Pattern (13): Behavioral Template Method Pattern
Design Patterns (14): Behavioral Strategy Patterns
Design Patterns (15): Behavioral Command Patterns
Design Pattern (16): Behavioral Chain of Responsibility Pattern
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. Chain of Responsibility Model
1 Overview
- A request can be processed by multiple objects, but each object has different processing conditions or permissions
- For example, if a company employee asks for leave, the leaders who can approve the leave include department heads, deputy general managers, general managers, etc.
- However, the number of days that each leader can approve is different. Employees must find different leaders to sign according to the number of days they want to ask for leave.
- In other words, employees must remember information such as the name, phone number and address of each leader, which increases the difficulty
definition
- To avoid coupling together
请求发送者
with多个请求处理者
- Chain all request handlers by remembering them from the previous
下一个对象的引用
object - When a request occurs, the request can be passed along this chain until an object handles it
2. Structure
The Chain of Responsibility pattern mainly includes the following roles:
- Abstract handler (Handler) role: define an interface for processing requests, including abstract processing methods and a subsequent connection
- Concrete Handler (Concrete Handler) role: implement the processing method of the abstract handler, judge whether the request can be processed, if it can handle the request, process it, otherwise transfer the request to its successor
- Client class (Client) role: Create a processing chain and submit a request to the specific processor object at the head of the chain. It does not care about the processing details and the delivery process of the request
3. Realize
Now need to develop a leave process control system
一天
The following leave only needs to be小组长
agreed- Leave
1天到3天
of absence requires部门经理
consent - The request
3天到7天
still needs to总经理
be agreed
The class diagram is as follows:
the code is as follows:
- leave of absence
@Getter
@AllArgsConstructor
public class LeaveRequest {
//姓名
private String name;
//请假天数
private int num;
//请假内容
private String content;
}
- abstract handler class
public abstract class Handler {
protected final static int NUM_ONE = 1;
protected final static int NUM_THREE = 3;
protected final static int NUM_SEVEN = 7;
// 该领导处理的请求天数区间
private int numStart;
private int numEnd;
// 声明后续者(声明上级领导)
private Handler nextHandler;
public Handler(int numStart) {
this.numStart = numStart;
}
public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}
// 设置上级领导对象
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
// 各级领导处理请求条的方法
protected abstract void handleLeave(LeaveRequest leave);
// 提交请求条
public final void submit(LeaveRequest leave) {
// 该领导进行审批
this.handleLeave(leave);
// 如果还有上级 并且请假天数超过了当前领导的处理范围
if (this.nextHandler != null && leave.getNum() > this.numEnd) {
// 提交给上级领导进行审批
this.nextHandler.submit(leave);
} else {
System.out.println("流程结束!");
}
}
}
- Specific processor
//小组长
public class GroupLeader extends Handler {
public GroupLeader() {
//小组长处理1-3天的请假
super(Handler.NUM_ONE, Handler.NUM_THREE);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("小组长审批:同意。");
}
}
//部门经理
public class Manager extends Handler {
public Manager() {
//部门经理处理3-7天的请假
super(Handler.NUM_THREE, Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("部门经理审批:同意。");
}
}
//总经理
public class GeneralManager extends Handler {
public GeneralManager() {
//部门经理处理7天以上的请假
super(Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "请假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("总经理审批:同意。");
}
}
- client test class
public class Client {
public static void main(String[] args) {
//请假条来一张
LeaveRequest leave = new LeaveRequest("小花",5,"身体不适");
//各位领导
GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
GeneralManager generalManager = new GeneralManager();
groupLeader.setNextHandler(manager);//小组长的领导是部门经理
manager.setNextHandler(generalManager);//部门经理的领导是总经理
//提交申请
groupLeader.submit(leave);
}
}
4. Advantages and disadvantages
advantage
- mode reduces the coupling of
请求发送者
the and接收者
- Enhanced the scalability of the system, new request processing classes can be added as needed,
满足开闭原则
- Enhanced the flexibility of assigning responsibilities to objects. When the workflow changes, you can dynamically change the members in the chain or modify their order, and you can also dynamically add or delete responsibilities
- Each class only needs to handle the work that it should handle, and pass the work that cannot be processed to the next object to complete, clarify the scope of responsibility of each class,
符合类的单一职责原则
shortcoming
- Compared with a long chain of responsibility, the processing of requests may involve multiple processing objects, and system performance will be affected to a certain extent
- The rationality of the establishment of the chain of responsibility depends on the client to ensure, which increases the complexity of the client
- System errors may occur due to incorrect setting of the chain of responsibility, such as circular calls
5. Source code analysis
- In javaWeb application development, FilterChain is a typical application of the chain of responsibility (filter) pattern
The following is the simulation implementation analysis of Filter:
- Simulate web request Request and web response Response
public interface Request{
}
public interface Response{
}
- Analog web filter Filter
public interface Filter {
public void doFilter(Request req,Response res,FilterChain c);
}
- Simulate implementation of concrete filters
public class FirstFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("过滤器1 前置处理");
// 先执行所有前置处理再倒序执行所有后置处理
chain.doFilter(request, response);
System.out.println("过滤器1 后置处理");
}
}
public class SecondFilter implements Filter {
@Override
public void doFilter(Request request, Response response, FilterChain chain) {
System.out.println("过滤器2 前置处理");
// 先执行所有前置处理再倒序执行所有后置处理
chain.doFilter(request, response);
System.out.println("过滤器2 后置处理");
}
}
- Simulate the implementation of the filter chain FilterChain
public class FilterChain {
private List<Filter> filters = new ArrayList<Filter>();
private int index = 0;
// 链式调用
public FilterChain addFilter(Filter filter) {
this.filters.add(filter);
return this;
}
public void doFilter(Request request, Response response) {
if (index == filters.size()) {
return;
}
Filter filter = filters.get(index);
index++;
filter.doFilter(request, response, this);
}
}
- test class
public class Client {
public static void main(String[] args) {
Request req = null;
Response res = null ;
FilterChain filterChain = new FilterChain();
filterChain.addFilter(new FirstFilter()).addFilter(new SecondFilter());
filterChain.doFilter(req,res);
}
}
输出结果:
过滤器1 前置处理
过滤器2 前置处理
过滤器2 后置处理
过滤器1 后置处理