まず、Chain of Responsibilityパターンの定義と特性
責任の定義された鎖(責任の連鎖)モード:Chain of Responsibilityパターンはまた、要求元と一緒に結合されているハンドラ要求複数のを回避するために、デューティ・チェーンと呼ばれ、すべてのリクエストが先行オブジェクトによって次覚えているプロセス参照オブジェクトとチェーンに接続され、要求があった場合、要求がこれまでにオブジェクトハンドルまで鎖に沿って送信することができる起こります。
Chain of Responsibilityパターンでは、顧客は単に要求を気にせずに要求し、転送処理の詳細を処理するために、責任のチェーンに要求を送信し、その責任の送信者と、ハンドラ要求チェーンが切り離さ要求します。
第二に、Chain of Responsibilityパターンの長所と短所
Chain of Responsibilityパターンは、オブジェクトの行動パターンであり、次のように、その主な利点は次のとおりです。
- オブジェクト間の結合を減少させます。このモードでは、最終的にオブジェクト要求および処理チェーン、お互いにも明確なメッセージを持っていない送信者と受信者の必要性である構造であるか分からないオブジェクトの必要性を可能にします。
- システムの拡張性を強化。開閉の原則を満たすために必要に応じて、要求処理の新しいカテゴリを追加することができます。
- オブジェクトに責任を割り当ての柔軟性を強化。ワークフローが変化した場合、あなたは動的にチェーン内のメンバーを変更したり、自分のためにも動的に追加または責任を削除することができ動員することができます。
- 責任の連鎖は、オブジェクト間の接続を簡素化します。各オブジェクトは、ちょうどif文のか···それ以外の場合は、多数の使用を回避する、他のすべてのハンドラを維持するために参照することなく、その後継への参照を保持します。
- 共同責任。唯一の自分の仕事のプロセスを扱う、次のオブジェクトの処理に渡すべきではありません各クラスの必要性は、単一の責任クラスの原則に沿って、責任範囲のすべての種類をクリアし、完了です。
次のように主な欠点は以下のとおりです。
- 私たちは、それぞれの要求を処理しなければならないことを保証することはできません。リクエストの受信者が明確ではないとして、我々はそれが処理されることを保証することはできませんが、リクエストがチェーンの最後に渡された可能性があり、処理されていません。
- 比較の長いデューティチェーンは、処理複数のオブジェクトを含むことができる要求を処理し、システムのパフォーマンスが影響を受けるであろう。
- お客様は終わりを確保するために、責任の確立チェーンの合理性に依存して、クライアントの複雑さを増す、このようなサイクルの呼び出しをもたらすことができるように誤った設定デューティチェーンと原因システムエラー、に起因する可能性があります。
第三に、Chain of Responsibilityパターンを達成するために
典型的には、データ構造は、デューティチェーンリンクリストデータによって実現されてもよいです。
デューティ・チェーンは、主に次の役割が含まれています。
- 抽象ハンドラ(ハンドラ)の役割:インターフェイスに処理要求を定義し、抽象後続の接続を含む処理方法。
- 詳細ハンドラは(コンクリートハンドラ)キャスト:要求は、それが前方にそうでない場合には、後継者に要求を処理することができれば、抽象ハンドラが処理方法を実装し、プロセスは、この要求か否かを判断します。
- 顧客クラス(クライアント)役割:処理チェーンを作成するには、ターゲットの特定のハンドラチェーンの最初の要求を提出し、それが転送処理の詳細を気にして、要求を処理しません。
図に示される構造:
責任の図チェーンに示すように、クライアントが配置されてもよいです。
コードは次のように実装されています。
パブリック クラスChainOfResponsibilityPattern { 公共 静的 ボイドメイン(文字列[]引数) { // 責任の組み立て鎖 ハンドラhandler1 = 新しい新しいConcreteHandler1(); ハンドラhandler2は = 新しい新しいConcreteHandler2(); handler1.setNext(handler2である); // リクエスト送信 handler1.handleRequestを( "TWO" ); } } // 抽象文字 抽象 クラスハンドラ { プライベートハンドラ次; 公共 無効SetNext(次ハンドラ) { この .next = 次に; } 公共ハンドラgetNextを() { 戻り次のページ; } // 要求を処理する方法 パブリック 抽象 ボイドのhandleRequest(要求文字列); } // 。具体的な処理の役割1 クラス ConcreteHandler1 延びハンドラ { 公共 ボイドのhandleRequest(文字列をリクエスト) { IF(request.equals( "1" )) { System.out.printlnは( "1が要求を処理するための具体的責任がある!" ); } 他 { IF(getNextを()!= NULL ) { getNextを()のhandleRequest(要求);. } 他 { するSystem.out.println( "NOプロセス要求!" ); } } } } // 特定処理ロール2 クラス ConcreteHandler2が延びハンドラ { 公共 ボイドのhandleRequest(要求文字列) { IF(request.equals( "TWO" )) { System.out.printlnは( "2は、要求を処理するための具体的責任があります!" )。 } 他 { IF(GetNextの()!= NULL ) { ;. getNextを()のhandleRequest(要求) } 他 { するSystem.out.println( "NOプロセス要求を!" ); } } } }
結果は以下の通りであります:
2特定のハンドラは、要求を処理するための責任があります!
第四には、アプリケーションの例には、Chain of Responsibilityパターン
承認モジュール用に書かれた要求に責任パターン設計のチェーン:に等しいか又はそれ以下の所定の学生が二日を残すよりもあれば、教師は承認することができる。以下、または7日に等しい、ディーンが承認、未満または10日に等しい、ディーンを承認することができる。他のせず私が承認します。
まず、抽象ハンドラであるリーダークラス(リーダー)を、定義し、それが次のリーダーのポインタへのポインタを含む次の抽象処理方法のhandleRequest(int型LeaveDays)プロセスのダミーバー;その後、クラスのカテゴリ(ClassAdviser)を定義し、抽象ハンドラのサブクラスであるクラス(DepartmentHead)とディーン・クラス(ディーン)の頭部は、ハンドラは、それに対処する資格がない場合は、自分の力に基づいて、親クラスのhandleRequest(int型LeaveDays)メソッドを実現する必要がある、特定のです最後まで次の特定のハンドラへの休暇のためのアプリケーション、顧客クラスは、ヘッド(教師)への休暇のための処理チェーン、および特定のハンドラチェーンを作成する責任があります。コードは次の通り:
パブリック クラスLeaveApprovalTest { 公共 静的 ボイドメイン(文字列[]引数) { // 責任の組み立て鎖 リーダーleader1 = 新しい新しいClassAdviser(); リーダーleader2 = 新しい新しいDepartmentHead(); リーダーleader3 = 新しい新しいディーン(); leader1.setNext(leader2) ; ; leader2.setNext(leader3) // リクエスト提出 (8 leader1.handleRequestを); } } // :リーダークラスによって抽象化 する抽象 クラスのリーダー { プライベート次にリーダー; 公共 ボイドSetNext(次リーダー) { この .next = 次; } 公共リーダーgetNextを() { 戻り次; } // 要求を処理する方法 パブリック 抽象 ボイドのhandleRequest(INT LeaveDays); } // 特定のハンドラを1 :クラスクラス クラス ClassAdviserは延びリーダー { 公共 ボイドのhandleRequest(INT LeaveDays) { IF(LeaveDays <= 2 ) { System.out.println( + "の日。" + LeaveDays "先生はあなたの休暇を承認" ); } 他 { IF(!GetNextの()= ヌル) { getNextを()のhandleRequest(LeaveDays);. } 他 { のSystem.out。 println(「休暇申請の承認を得ることなく、数、あまりにも多くの日を残して!」); } } } } // 治療における特定の2:クラスの頭 クラスは DepartmentHead 拡張リーダーを { 公共 空のhandleRequest(int型LeaveDays) { IF(LeaveDays <= 7。 ) { System.out.printlnは( + "あなたはディーンを残す" LeaveDays + "の日。" ); } 他 { IF(!GetNextの()= ヌル) { getNextを()のhandleRequest(。 LeaveDays); } 他 { System.out.printlnは(「あまりにも多くの休暇日数休暇申請の承認なし!」); } } } } // 3での具体的な処理:ディーン・クラスの クラス・ディーン拡張リーダー { 公共 無効のhandleRequest(int型LeaveDays) { IF(LeaveDays <= 10 ) { System.out.printlnは( + "会長のご承認を残す" LeaveDays + "の日。" ); } 他 { IF(getNextを()!= nullのを) { getNextを()のhandleRequest(LeaveDays);. } 他 { System.out.printlnは( "休暇申請の承認なしに、あまりにも多くの休暇の日!" ); } } } }
次のような結果を操作します:
ディーンは8日、あなたの休暇を承認します。
あなたは今学長クラスを追加する場合は、次のように、生徒たちは、それはまた、非常にシンプルで、20日間の休暇を与えることがあります。
// 特定の処理4により:学長クラス クラス DeanOfStudies 拡張リーダー { 公共 空のhandleRequest(int型LeaveDays) { IF(LeaveDays <= 20である) { System.out.printlnはを( + LeaveDays +「デイ"あなたの承認学長を残します" 。 " ); } 他 { IF!(getNextを()= ヌル) { getNextを()のhandleRequest(LeaveDays);. } 他 { System.out.printlnは( "「休暇申請の承認なしに、あまりにも多くの休暇日数!)。 } } } }
その後、学長にアセンブリに直接責任のチェーンに追加します。
リーダーleader4 = 新しいDeanOfStudies(); leader3.setNext(leader4)。
第五に、責任のパターンのシナリオの連鎖
フロント、以下のアプリケーションシナリオを記述し、Chain of Responsibilityパターンの構造と特性について言われている、Chain of Responsibilityパターンは、一般的に次のような状況で使用されています。
- オブジェクトの複数のオブジェクトが自動的にリクエスト処理ランタイムによって決定される要求を処理することができます。
- 動的要求指定にオブジェクトのセットを処理する、または新しいプロセッサを追加します。
- 明示的にハンドラを要求せずに、複数のハンドラに要求を提出します。
拡張六、Chain of Responsibilityパターン
以下の2つのケースデューティチェーン。
- 責任パターンの純粋なチェーン:要求を処理するために1つのハンドラオブジェクトと特定のハンドラによって受信されなければならない要求が2つのだけのアクションのいずれか取ることができます。自分の治療(責任を);にバックを渡します家の下で治療。
- 不純なデューティチェーン:要求は、残りの次のホーム責任に渡された場合の一部の責任を負うために、特定のオブジェクト・ハンドラで許可され、最終的な要求は、任意の受信側オブジェクトによって受信することができません。