責任チェーンモード

14609 ワード

個人理解:責任チェーンは定義されたクラスHandlerの中に属性もHandlerクラスがあり、要求を実行する方法には要求を受信するパラメータ、すなわちhandler(request)が必要である.
 
文章はhttp://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.htmlに抜粋した.
责任链 模式_第1张图片
 
責任チェーン・モードの役割は次のとおりです.
●抽象処理者(Handler)ロール:処理要求のインタフェースを定義します.必要に応じて、インタフェースは、次の参照を設定して返す方法を定義できます.このロールは通常、Java抽象クラスまたはJavaインタフェースによって実現されます.上の図のHandlerクラスの集約関係は、特定のサブクラスの下位への参照を与え、抽象的な方法handleRequest()は、サブクラス処理要求の動作を規範化している.
●具体的な処理者(ConcreteHandler)の役割:具体的な処理者は要求を受けた後、要求を処理するか、あるいは要求を下家に伝えるかを選択することができる.具体的な処理者は、下家への参照を持っているため、必要に応じて、具体的な処理者は下家にアクセスすることができる.
 
抽象プロセッサの役割
public abstract class Handler {
    
    /**
     *          
     */
    protected Handler successor;
    /**
     *          ,                
     *            ,               
     */
    public abstract void handleRequest();
    /**
     *     
     */
    public Handler getSuccessor() {
        return successor;
    }
    /**
     *     ,         
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
}

 
具体的なプロセッサの役割
public class ConcreteHandler extends Handler {
    /**
     *     ,         
     */
    @Override
    public void handleRequest() {
        /**
         *             
         *    ,             
         *     ,     
         */
        if(getSuccessor() != null)
        {            
            System.out.println("    ");
            getSuccessor().handleRequest();            
        }else
        {            
            System.out.println("    ");
        }
    }

}

 
クライアントクラス
public class Client {

    public static void main(String[] args) {
        //     
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler();
        handler1.setSuccessor(handler2);
        //    
        handler1.handleRequest();
    }

}

 
クライアントは、2つのプロセッサオブジェクトを作成し、最初のプロセッサオブジェクトの下位が2番目のプロセッサオブジェクトであり、2番目のプロセッサオブジェクトが下位でないことを指定していることがわかります.クライアントは、要求を最初のプロセッサオブジェクトに渡します.
この例の伝達ロジックは非常に簡単であるため、下位があれば、下位処理に伝達される.下家がなければ、自分で処理します.したがって、第1のプロセッサオブジェクトは、要求を受信すると、第2のプロセッサオブジェクトに要求を渡す.2番目の処理者の対象が下家していないため,要求を自分で処理する.アクティビティシーケンス図を以下に示します.
责任链 模式_第2张图片
 
 
上記の例は単純にhandleチェーンが形成されているだけであるが,ユーザの要求を受け入れていないため,handleのインタフェースを修正し,その処理方法をhadlder(request)に変更し,handlerチェーンでrequest要求を処理する必要がある.
package chain;

public interface Request {
	
	public String request();
	
	public void setRequest(String message);
	
}

 
package chain;

public class MyRequest implements Request {

	String message;
	
	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}

	public MyRequest(String message){
		this.message = message;
	}

	@Override
	public String request() {
		System.out.println("myrequest function");
		return this.getMessage();
	}

	@Override
	public void setRequest(String message) {
		this.setMessage(message);
	}
	
}

 
package chain;

public abstract class Handler {
    
    /**
     *          
     */
    protected Handler successor;
    /**
     *          ,                
     *            ,               
     */
    public abstract void handleRequest(Request request);
    /**
     *     
     */
    public Handler getSuccessor() {
        return successor;
    }
    /**
     *     ,         
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    
}

 
package chain;

public class ConcreteHandler extends Handler {

	@Override
	public void handleRequest(Request request) {
		/**
         *             
         *    ,             
         *     ,     
         */
		request.setRequest(request.request()+ "------ ConcreteHandler ------");
		if(this.getSuccessor()!=null){
			System.out.println("       ConcreteHandler:"+ request.request());
			this.getSuccessor().handleRequest(request);
		}else{
			System.out.println("       ConcreteHandler:" + request.request());
		}
	}

}

 
package chain;

public class ConcreteHandler2 extends Handler {

	@Override
	public void handleRequest(Request request) {
		/**
         *             
         *    ,             
         *     ,     
         */
		request.setRequest(request.request()+ " ------ ConcreteHandler2 ------");
		if(this.getSuccessor()!=null){
			System.out.println("       ConcreteHandler2:"+ request.request());
			this.getSuccessor().handleRequest(request);
		}else{
			System.out.println("       ConcreteHandler2:" + request.request());
		}
	}

}

 
package chain;

public class Client {

    public static void main(String[] args) {
        //     
        Handler handler1 = new ConcreteHandler();
        Handler handler2 = new ConcreteHandler2();
        
//        handler1.setSuccessor(handler2);
//        MyRequest myRequest = new MyRequest("huangbiao");
//        //    
//        handler1.handleRequest(myRequest);
        
        handler2.setSuccessor(handler1);
        MyRequest myRequest = new MyRequest("huangbiao");
        //    
        handler2.handleRequest(myRequest);
        
    }

}

印刷結果:
myrequest function
myrequest function
次のリクエストConcreteHandler 2:huangbiao-----ConcreteHandler 2-----へ
myrequest function
myrequest function
最後のリクエストConcreteHandler:huangbiao------ConcreteHandler 2------ConcreteHandler------
 
 
シーンの操作
会食費の管理を申請する機能を考えてみましょう.
多くの会社は、プロジェクトグループや部門が会社に会食費用を申請して、プロジェクトグループのメンバーや部門のメンバーを組織して会食活動を行うことができるという福祉です.
会食費用の申請の大まかな流れは一般的に、申請者が先に申請書を記入し、それから指導者に審査・認可を渡し、申請が承認されると、指導者は申請者に審査・認可の通過を通知し、それから申請者が財務に行って費用を受け取り、承認されなければ、指導者は申請者に審査・認可が通過していないことを通知する.
異なるレベルのリーダーは、承認の額が異なります.例えば、プロジェクトマネージャは500元以内の申請しか承認できません.部門のマネージャーは1000元以内の申請を審査・認可することができる.総経理は任意の額の申請を審査することができます.
つまり、ある人が会食費用の申請をした後、その要求はプロジェクトマネージャー、部門マネージャー、社長の一人の指導者を通じて相応の処理を行うが、申請を提出した人は最終的に誰が彼の要求を処理するか分からない.一般的な申請者は自分の申請をプロジェクトマネージャーに提出する.最後に社長が彼の要求を処理したのかもしれない.
責任チェーンモデルを使用して、上記の機能を実現することができます.ある人が会食費用申請の要求を提出した後、この要求はプロジェクトマネージャ—〉部門マネージャ—〉社長のようなリーダーシップ処理チェーンで伝達され、要求を出した人は誰が彼の要求を処理するか分からないので、各リーダーは自分の職責範囲に基づいて、要求を処理するか、より高いレベルのリーダーに要求を渡すかを判断するには、リーダーが処理すれば、伝達は終了します.
各リーダーの処理を独立させ、個別の職責処理オブジェクトとして実現し、共通の抽象的な親職責オブジェクトを提供する必要があります.これにより、クライアントで職責チェーンを動的に組み合わせ、異なる機能要件を実現することができます.
   责任链 模式_第3张图片
 
ソースコード
抽象プロセッサロールクラス
public abstract class Handler {
    /**
     *             
     */
    protected Handler successor = null;
    /**
     *     
     */
    public Handler getSuccessor() {
        return successor;
    }
    /**
     *             
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    /**
     *          
     * @param user       
     * @param fee         
     * @return                  
     */
    public abstract String handleFeeRequest(String user , double fee);
}

 
具体的なプロセッサの役割
public class ProjectManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        
        String str = "";
        //         ,   500  
        if(fee < 500)
        {
            //    ,   ,        
            if("  ".equals(user))
            {
                str = "  :      【" + user + "】     ,   " + fee + " ";    
            }else
            {
                //        
                str = "  :       【" + user + "】     ,   " + fee + " ";
            }
        }else
        {
            //  500,             
            if(getSuccessor() != null)
            {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

 
public class DeptManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        
        String str = "";
        //          1000  
        if(fee < 1000)
        {
            //    ,   ,        
            if("  ".equals(user))
            {
                str = "  :      【" + user + "】     ,   " + fee + " ";    
            }else
            {
                //        
                str = "  :       【" + user + "】     ,   " + fee + " ";
            }
        }else
        {
            //  1000,             
            if(getSuccessor() != null)
            {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

 
public class GeneralManager extends Handler {

    @Override
    public String handleFeeRequest(String user, double fee) {
        
        String str = "";
        //        ,        ,      
        if(fee >= 1000)
        {
            //    ,   ,        
            if("  ".equals(user))
            {
                str = "  :     【" + user + "】     ,   " + fee + " ";    
            }else
            {
                //        
                str = "  :      【" + user + "】     ,   " + fee + " ";
            }
        }else
        {
            //           ,    
            if(getSuccessor() != null)
            {
                return getSuccessor().handleFeeRequest(user, fee);
            }
        }
        return str;
    }

}

 
クライアントクラス
public class Client {

    public static void main(String[] args) {
        //       
        Handler h1 = new GeneralManager();
        Handler h2 = new DeptManager();
        Handler h3 = new ProjectManager();
        h3.setSuccessor(h2);
        h2.setSuccessor(h1);
        
        //    
        String test1 = h3.handleFeeRequest("  ", 300);
        System.out.println("test1 = " + test1);
        String test2 = h3.handleFeeRequest("  ", 300);
        System.out.println("test2 = " + test2);
        System.out.println("---------------------------------------");
        
        String test3 = h3.handleFeeRequest("  ", 700);
        System.out.println("test3 = " + test3);
        String test4 = h3.handleFeeRequest("  ", 700);
        System.out.println("test4 = " + test4);
        System.out.println("---------------------------------------");
        
        String test5 = h3.handleFeeRequest("  ", 1500);
        System.out.println("test5 = " + test5);
        String test6 = h3.handleFeeRequest("  ", 1500);
        System.out.println("test6 = " + test6);
    }

}

 
実行結果
责任链 模式_第4张图片
 
純粋と不純の責任チェーンモデル
1つの純粋な責任チェーンモデルは、1つの具体的な処理者オブジェクトが2つの行為の中で1つしか選択できないことを要求しています.1つは責任を負うことであり、2つは責任を下の家に押し付けることです.ある特定の処理者オブジェクトが一部の責任を負った後、また責任を下に伝えることは許されない.
純粋な責任チェーンモードでは、要求はある処理者オブジェクトに受信されなければならない.不純な責任チェーンモードでは、要求は最終的に受信側オブジェクトに受信されないことができる.
純粋な責任チェーンモデルの実際の例は見つけにくいが,一般的に見られる例は不純な責任チェーンモデルの実現である.不純な責任チェーンは責任チェーンモデルではないと考えている人もいるが、これは理にかなっているかもしれない.しかし、実際のシステムでは、純粋な責任チェーンは見つけにくい.責任チェーンが不純であることを堅持すれば、責任チェーンモデルはあまり意味がない.