この記事の出所: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、基本的な考え方
Chain of Responsibilityパターンは、オブジェクト行動パターンです。責任のパターンのチェーンでは、次の上のオブジェクトのそれぞれによって参照される多くのオブジェクトは、鎖構造を形成するために一緒に接続されています。要求を処理する権利鎖上の特定のオブジェクトまで、この連鎖移動要求です。クライアントを要求すると、システムが動的に再編成し、クライアントに影響を与えることなく、責任のオブジェクトを割り当てることができ、要求を処理するためにチェーン上のどのオブジェクトを知りません。
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("直接处理请求了...");
}
}
}
三、春Frameworkアプリケーション
1、のDispatcherServletクラス
DispatcherServletのコアメソッドdoDispatch。各インターセプター自体に登録することができるHandlerInterceptorメンテナンスの専用コレクションに要求を直接処理しないHandlerExecutionChainは、要求は、登録プロセッサに割り当てられ、それ自体と、処理論理デューティー鎖間の結合の程度を低減するために、責任の連鎖を行います。
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);
}
}
}
第四に、モデルの概要
- 別個の要求、および処理ロジック、改良されたデカップリング・システムを実現するための柔軟性。
- 責任のチェーンが長すぎると、パフォーマンスがテストが複雑になり、ドロップします。
- シナリオ:、去る支払い、および他の一般的な費用の承認プロセス。
第五に、ソースコードのアドレス
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent