дизайн Java-модель, описанная в (15): цепочке обязанностей

Эта статья Источник: GitHub · Нажмите здесь || GitEE · Нажмите здесь

Один из них, описанных сцен из жизни

1, оставить процесс утверждения

общий процесс утверждения отпусков компании: оставить дни

当 day<=3   天,项目经理审批
当 3<day<=5 天,部门经理审批
当 day>5    天,CEO审批

2, схема последовательности операций

3, реализация кода

public class C01_InScene {
    public static void main(String[] args) {
        // 组装责任链
        AuditHandler h1 = new CeoManger();
        AuditHandler h2 = new DeptManger();
        AuditHandler h3 = new ProjectManger();
        h3.setSuccessor(h2);
        h2.setSuccessor(h1);
        /*
         * 测试输出
         * 项目经理无权审批
         * 部门经理无权审批
         * CEO审批:同意【Cicada】,请假【6】天
         */
        h3.handleLeaveDay("Cicada",6);
    }
}
abstract class AuditHandler {
    //持有下一个处理请求的对象
    protected AuditHandler successor = null;
    public AuditHandler getSuccessor() {
        return successor;
    }
    public void setSuccessor(AuditHandler successor) {
        this.successor = successor;
    }
    public abstract void handleLeaveDay (String user,Integer day);
}

/**
 * 项目经理审批
 */
class ProjectManger extends AuditHandler{
    @Override
    public void handleLeaveDay(String user, Integer day) {
        if (day <= 3){
            System.out.println("项目经理审批:同意【"+user+"】,请假【"+day+"】天");
        } else {
            System.out.println("项目经理无权审批");
            if (getSuccessor() != null){
                getSuccessor().handleLeaveDay(user,day);
            }
        }
    }
}
/**
 * 部门经理审批
 */
class DeptManger extends AuditHandler{
    @Override
    public void handleLeaveDay(String user, Integer day) {
        if (day > 3 && day <= 5){
            System.out.println("部门经理审批:同意【"+user+"】,请假【"+day+"】天");
        } else {
            System.out.println("部门经理无权审批");
            if (getSuccessor() != null){
                getSuccessor().handleLeaveDay(user,day);
            }
        }
    }
}
/**
 * CEO审批
 */
class CeoManger extends AuditHandler{
    @Override
    public void handleLeaveDay(String user, Integer day) {
        if (day > 5){
            System.out.println("CEO审批:同意【"+user+"】,请假【"+day+"】天");
        } else {
            if (getSuccessor() != null){
                getSuccessor().handleLeaveDay(user,day);
            }
        }
    }
}

Во-вторых, цепочка обязанностей

1, основная концепция

Цепочка обязанностей является объектно-моделью поведения. В цепочке ответственности шаблона, многие объекты ссылаются друг объекта на следующем соединены вместе, чтобы сформировать структуру цепи. В этом запросе переноса цепи до определенного объекта на правой цепи, чтобы обработать запрос. Запрос клиента не знает, какой объект на цепочке для обработки запроса, что позволяет системе динамически реорганизовывать и назначить ответственность объектов, не влияя на клиент.

2, основной роли

(1), роль абстрактного обработчика

Определение запроса обработки на интерфейс. Интерфейс может быть установлен, чтобы дать метод и возвращает ссылку на следующий объект. Эта роль, как правило, состоит из Java абстрактных классов или интерфейса Java.

(2) конкретно рассматривается роль

ПОДРОБНОЕ Процессор по запросу, обработка запроса может быть выбрана из, или объекта запросы к следующему. Из-за конкретный обработчик содержит ссылку на следующий дом.

3, иллюстрирует картину

4, исходный код для достижения

public class C02_Chain {
    public static void main(String[] args) {
        // 组装责任链
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        handler1.setHandler(handler2);
        // 提交请求
        handler1.handlerRequest();
    }
}
/**
 * 抽象处理者角色
 */
abstract class Handler {
    /*
     * 持有后续的责任对象
     */
    protected Handler handler;
    /**
     * 处理请求的方法
     */
    public abstract void handlerRequest();
    public Handler getHandler() {
        return handler;
    }
    public void setHandler(Handler handler) {
        this.handler = handler;
    }
}
/**
 * 具体处理者角色
 */
class ConcreteHandler extends Handler{
    /**
     * 调用该方法处理请求
     */
    @Override
    public void handlerRequest() {
        /*
         * 判断是否有后续的责任对象,没有就出来请求,有就直接放过
         */
        if(getHandler() != null){
            System.out.println("放过请求,下个对象处理...");
            getHandler().handlerRequest();
        } else{
            System.out.println("直接处理请求了...");
        }
    }
}

Три, Spring Framework приложений

1, DispatcherServlet класс

Основные методы DispatcherServlet doDispatch. HandlerExecutionChain только коллекция обслуживания HandlerInterceptor, который может быть зарегистрирован в соответствующем перехватчик сам по себе не непосредственно обрабатывать запрос, запрос присвоен регистрационный процессор выполняет цепочку ответственности, чтобы уменьшить степень сцепления между собой и дежурным цепи обработки логики.

HandlerExecutionChain mappedHandler = null;
mappedHandler = this.getHandler(processedRequest);
mappedHandler.applyPreHandle(processedRequest, response);
mappedHandler.applyPostHandle(processedRequest, response, mv);

2, HandlerExecutionChain 类

Существует несколько методов анализа, описанные здесь, способ запрашиваются из класса doDispatch DispatcherServlet.

  • Получает перехватчик, выполнить метод preHandle.
boolean applyPreHandle(HttpServletRequest request, 
                       HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
            HandlerInterceptor interceptor = interceptors[i];
            if (!interceptor.preHandle(request, response, this.handler)) {
                this.triggerAfterCompletion(request, response, (Exception)null);
                return false;
            }
        }
    }
    return true;
}
  • В applyPreHandle процесс, выполняемый метод triggerAfterCompletion.
void triggerAfterCompletion(HttpServletRequest request, 
                            HttpServletResponse response, Exception ex) throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for(int i = this.interceptorIndex; i >= 0; --i) {
            HandlerInterceptor interceptor = interceptors[i];
            try {
                interceptor.afterCompletion(request, response, this.handler, ex);
            } catch (Throwable var8) {
                logger.error("HandlerInterceptor.afterCompletion threw exception", var8);
            }
        }
    }
}
  • Получает перехватчик, выполнить метод applyPostHandle.
void applyPostHandle(HttpServletRequest request, 
                     HttpServletResponse response, ModelAndView mv) 
                     throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for(int i = interceptors.length - 1; i >= 0; --i) {
            HandlerInterceptor interceptor = interceptors[i];
            interceptor.postHandle(request, response, this.handler, mv);
        }
    }
}

В-четвертых, резюме модель

  1. Отдельный запрос, и логика обработки, гибкость, чтобы достичь улучшенной системы расцепления;
  2. Когда цепь ответственности слишком долго, производительность будет падать, тестирование усложняется;
  3. Сценарий: отпуск, оплатить и другие общие расходы процесс утверждения;

В-пятых, адрес исходного кода

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

рекомендация

отwww.cnblogs.com/cicada-smile/p/11716928.html
рекомендация