Chapter 16 Behavioral Model—Chain of Responsibility Model


Behavioral patterns are used to describe the complex flow control of programs at runtime, that is, to describe how multiple classes or objects cooperate with each other to complete tasks that a single object cannot complete alone. It involves the allocation of responsibilities between algorithms and objects. Behavioral patterns are divided into class behavior patterns and object behavior patterns:

  • Class behavior pattern: using inheritance mechanism to dispatch behavior between classes

  • Object behavior pattern: Use composition or aggregation to distribute behavior among objects

Since the combination relationship or aggregation relationship is less coupled than the inheritance relationship and satisfies the "principle of composite reuse", the object behavior pattern has greater flexibility than the class behavior pattern.

Behavioral patterns are divided into:

  • template method pattern
  • strategy pattern
  • command mode
  • chain of responsibility model
  • state mode
  • Observer pattern
  • intermediary pattern
  • iterator pattern
  • visitor mode
  • Memo mode
  • interpreter mode

The above 11 behavioral patterns, except for the template method pattern and the interpreter pattern, which are quasi-behavioral patterns, the others all belong to the object behavioral pattern.

chain of responsibility model

Chain of responsibility model : Also known as the chain of responsibility model, in order to prevent the request sender from being coupled with multiple request handlers, all request handlers are connected into a chain by remembering the reference of the next object through the previous object ; when When a request occurs, the request can be passed along this chain until an object handles it.

solved problem

In real life, there are often cases where 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 Head], [Deputy General Manager], [General Manager], etc., but the number of days that each leader can approve is different, and employees must find one based on the number of days they want to ask for leave. Different leaders sign, which means employees must remember the name, phone number, address and other information of each leader, which increases the difficulty.

structure

  • Abstract handler (Handler) role: defines an interface for processing requests, including abstract processing methods and a subsequent connection.

  • Concrete Handler role: Implement the processing method of the abstract handler to determine whether the request can be processed. If the request can be processed, process it, otherwise the request will be transferred to its successor.

  • Client class (Client) role: Creates a processing chain and submits a request to the specific handler object of the chain head. It does not care about the processing details and request delivery process.

example

insert image description here

leave of absence

@Getter
public class LeaveRequest {
    
    
    //姓名
    private String name;
    //请假天数
    private int num;
    //请假内容
    private String content;

    public LeaveRequest(String name, int num, String content) {
    
    
        this.name = name;
        this.num = num;
        this.content = content;
    }
}

abstract handler

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 Handler(Handler nextHandler) {
    
    
        this.nextHandler = nextHandler;
    }
    //各级领导处理请求条的方法
    protected  abstract  void handleLeave(LeaveRequest leaveRequest);
    //提交请求条
    public final void  submit(LeaveRequest leaveRequest){
    
    
        if(leaveRequest.getNum()>NUM_SEVEN){
    
    
            System.out.println("请假天数过多");
            return;
        }
        //该领导进行审批
        this.handleLeave(leaveRequest);
        if(this.nextHandler != null && leaveRequest.getNum() > this.numEnd){
    
    
            //提交给上级领导进行审批
            this.nextHandler.submit(leaveRequest);
        }else {
    
    
            System.out.println("流程结束!");
        }
    }
}

Specific processor

public class GroupLeader extends Handler{
    public GroupLeader() {
        super(0,Handler.NUM_ONE);
    }

    @Override
    protected void handleLeave(LeaveRequest leaveRequest) {
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");
        System.out.println("小组长审批:同意");
    }
}
public class Manager extends Handler{
    public Manager() {
        super(Handler.NUM_ONE, Handler.NUM_THREE);
    }
    @Override
    protected void handleLeave(LeaveRequest leaveRequest) {
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");
        System.out.println("部门经理审批:同意");
    }
}
public class GeneralManager extends Handler{
    public GeneralManager() {
        super(Handler.NUM_THREE, Handler.NUM_SEVEN);
    }


    @Override
    protected void handleLeave(LeaveRequest leaveRequest) {
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");
        System.out.println("总经理审批:同意");
    }
}

customer class

public class Client {
    
    
    public static void main(String[] args) {
    
    
        //创建一个请假条对象
        LeaveRequest leaveRequest = new LeaveRequest("小明", 7, "身体不适");
        //创建各级领导对象
        GroupLeader groupLeader = new GroupLeader();//小组长
        Manager manager = new Manager();//部门经理
        GeneralManager generalManager = new GeneralManager();//总经理
        //设置处理者链
        groupLeader.setNextHandler(manager);
        manager.setNextHandler(generalManager);
        //小明提交请假申请
        groupLeader.submit(leaveRequest);
    }
}

Problems

advantage:

  • Reduces the coupling between objects, this mode reduces the coupling between request sender and receiver.

  • The scalability of the system is enhanced, and new request processing classes can be added as needed , satisfying the principle of opening and closing.

  • It enhances the flexibility of assigning responsibilities to objects . When the workflow changes, members in the chain can be dynamically changed or their order can be modified, and responsibilities can also be added or deleted dynamically.

  • The chain of responsibility simplifies the connection between objects. An object only needs to maintain a reference to its successor, and does not need to maintain references to all other handlers . This avoids the use of numerous if or if...else statements.

  • Responsibility sharing , each class only needs to handle the work that it should handle, and the work that cannot be handled is passed to the next object for completion, clarifying the scope of responsibilities of each type, and conforming to the single responsibility principle of the class.

shortcoming:

  • There is no guarantee that every request will be processed. Since a request has no clear recipient, there is no guarantee that it will be processed, and the request may not be processed until it reaches the end of the chain.
  • Compared with a longer chain of responsibilities, the processing of requests may involve multiple processing objects, and system performance will be affected to a certain extent.
  • The rationality of the chain of responsibility establishment must be ensured by the client, which increases the complexity of the client. System errors may occur due to incorrect settings of the chain of responsibility, such as circular calls.

JavaWeb source code - FilterChain

In JavaWeb application development, FilterChain is a typical application of the chain of responsibility model. The following is a simulation implementation analysis of Filter:

Simulate Web request Request and Web response Response:

public interface Request{
    
    
}

public interface Response{
    
    
}

Simulate Web filter Filter:

public interface Filter {
    
    
  void doFilter(Request req,Response res,FilterChain c);
}

Simulate implementation of specific filters:

public class FirstFilter implements Filter {
    
    
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
    
    
        System.out.println("过滤器1 前置处理");
        // 先执行所有request再倒序执行所有response
        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 前置处理");
        // 先执行所有request再倒序执行所有response
        chain.doFilter(request, response);
        System.out.println("过滤器2 后置处理");
    }
}

Simulate the implementation of filter chain FilterChain:

public class FilterChain {
    
    
    private List<Filter> filters = new ArrayList<>();
    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 后置处理

おすすめ

転載: blog.csdn.net/qq_50985215/article/details/130970127