Design Pattern (16): Behavioral Chain of Responsibility Pattern

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



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:
insert image description here
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 后置处理

Guess you like

Origin blog.csdn.net/qq_35512802/article/details/131212226