定義: 複数のオブジェクトにリクエストを処理する機会を与えることで、リクエストの送信者と受信者の間の結合関係を回避します。これらのオブジェクトはチェーンに接続され、リクエストはオブジェクトが処理するまでチェーンに沿って渡されます。
タイプ: 動作パターン
クラス図:
最初にコードを見てみましょう:
public void test(int i, Request request){ if(i==1){ Handler1.response(request); }else if(i == 2){ Handler2.response(request); }else if(i == 3){ Handler3.response(request); }else if(i == 4){ Handler4.response(request); }else{ Handler5.response(request); } }
コードのビジネス ロジックは次のようなものです: 整数 i とリクエスト request。 i に応じて、誰がリクエストを処理するかが決まります。i==1 の場合は Handler1 によって処理され、i==2 の場合は Handler2 によって処理されます。プログラミングでは、このビジネス処理方法は非常に一般的であり、リクエストを処理するすべてのクラスには、リクエストを処理するための一連の責任を形成するために接続された if...else... 条件判断ステートメントが含まれています。この方法の利点は、非常に直感的で、シンプルかつ明確で、保守が比較的容易であることです。しかし、この方法にはいくつかの厄介な問題もあります。
コードの肥大化: 通常、実際のアプリケーションでの判定条件は、どちらかを判断するのがそれほど単純ではありません。 1 ですか、それとも 2 ですか? 複雑な計算が必要になる場合や、データベースへのクエリなどが必要になる場合があります。さらに多くの判定条件がある場合、この if...else... ステートメントには多くの追加のコードが含まれます。基本的には読めなくなります。
高度な結合: リクエストを処理するためのクラスを追加し続けたい場合は、else if 判定条件を追加し続ける必要があります。さらに、この条件判定の順序もハードコーディングする必要があります。 、この条件文のみを変更できます。
欠点が明らかになったので、それらを解決する方法を見つけなければなりません。このシナリオのビジネス ロジックは非常に単純です。条件 1 が満たされている場合は Handler1 によって処理され、条件 2 が満たされていない場合は Handler2 によって処理されます。 、条件が終了するまで、引き続き引き継がれます。実は改善方法も非常にシンプルで、判定条件部分を処理クラスに組み込むというもので、これが責任連鎖モデルの原理です。
責任連鎖モデルの構造
責任連鎖モデルのクラス図は非常に単純で、抽象処理クラスとその実装クラスのセットで構成されます。
抽象処理クラス: 抽象処理クラスには主にポインターが含まれます。次の処理クラスへのメンバー変数 nextHandler とリクエストを処理するためのメソッド handRequest メソッドの主な考え方は、処理条件が満たされた場合はこの処理クラスが処理し、そうでない場合は nextHandler によって処理されるということです。 。
特定処理クラス: 特定処理クラスは主に特定の処理ロジックと処理に適用される条件を実装します。
例
抽象ハンドラー (Handler) 役割: 要求されたインターフェースを定義します。必要に応じて、次のオブジェクトへの参照を設定して返すメソッドを定義できます。
ConcreteHandler ロール: 処理できる場合、リクエストは処理されます。処理できない場合、リクエストは処理のために次のパーティに渡されます。これは、処理できるリクエストを処理し、次のホームにアクセスできることを意味します。
上記のモードのテスト コードは次のとおりです:
package chainOfResp; /** *描述:抽象处理角色 */ public abstract class Handler { protected Handler successor; /** *描述:处理方法 */ public abstract void handlerRequest(String condition); public Handler getSuccessor() { return successor; } public void setSuccessor(Handler successor) { this.successor = successor; } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandler1 extends Handler { @Override public void handlerRequest(String condition) { // 如果是自己的责任,就自己处理,负责传给下家处理 if(condition.equals("ConcreteHandler1")){ System.out.println( "ConcreteHandler1 handled "); return ; }else{ System.out.println( "ConcreteHandler1 passed "); getSuccessor().handlerRequest(condition); } } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandler2 extends Handler { @Override public void handlerRequest(String condition) { // 如果是自己的责任,就自己处理,负责传给下家处理 if(condition.equals("ConcreteHandler2")){ System.out.println( "ConcreteHandler2 handled "); return ; }else{ System.out.println( "ConcreteHandler2 passed "); getSuccessor().handlerRequest(condition); } } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandlerN extends Handler { /** * 这里假设n是链的最后一个节点必须处理掉 * 在实际情况下,可能出现环,或者是树形, * 这里并不一定是最后一个节点。 * */ @Override public void handlerRequest(String condition) { System.out.println( "ConcreteHandlerN handled"); } }
package chainOfResp; /** *描述:测试类 */ public class Client { /** *描述: */ public static void main(String[] args) { Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handlern = new ConcreteHandlerN(); //链起来 handler1.setSuccessor(handler2); handler2.setSuccessor(handlern); //假设这个请求是ConcreteHandler2的责任 handler1.handlerRequest("ConcreteHandler2"); } }例を挙げると、おもちゃ工場の生産ワークショップでは、組み立てラインは責任の連鎖です。たとえば、おもちゃの飛行機にはシェルがあります。アセンブラ、エンジンアセンブラ、プロペラアセンブラ、パッカーズで構成されます。このオブジェクトが誰に流れても、その人は自分が担当する部分のインストールを担当します。この部分のインストールが完了すると、すべての環境が完了するまで次のリンクに流れます。これは生涯にわたる責任の連鎖です。品質検査チェーンもあり、品質検査もシェル検査、エンジン検査、プロペラ検査、包装検査など複数の部分に分かれています。検査員に担当箇所の検査を任せた場合、問題がなければ直接引き取り、すべての検査が完了するまで次の検査員に引き継がれます。どちらも責任チェーンですが、違いは、全員が生成された責任チェーンを処理し、その一部を処理するのに対し、品質検査の責任チェーンは判断され、処理されるか処理されないかのいずれかであるという点です。これらは責任連鎖の 2 つの分類であり、後者は純粋責任連鎖と呼ばれ、前者は不純責任連鎖と呼ばれます。実際のアプリケーションでは、最も一般的なのは不純責任連鎖です。純粋な責任の連鎖をシミュレートすることによって処理されます。
責任連鎖モデルのメリットとデメリット
責任連鎖モデルは、条件判定をさまざまな処理クラスに分散し、各処理クラスの優先処理順序を任意に設定できるため、if…else…に比べて結合度が低くなります。責任連鎖モデルにも、if...else... ステートメントの欠点と同じ欠点があります。つまり、責任連鎖が見つかると、正しい処理クラスが見つかる前にすべての判断条件が実行される必要があります。比較的長い場合、パフォーマンスの問題はより深刻です。
責任の連鎖パターンの適用可能なシナリオ
最初の例と同様に、責任の連鎖を整理するために if...else... ステートメントを使用するのが不十分で、コードが悪く見える場合は、次の連鎖を使用できます。リファクタリングする責任パターン。
概要
責任連鎖モデルは、実際には、if...else... ステートメントの柔軟なバージョンであり、これらの判断条件ステートメントを各処理クラスに配置します。これには、より柔軟であるという利点もあります。たとえば、処理クラス間の関係を設定するときは、処理クラスの前後のロジック間の条件関係を決定することに特に注意し、チェーン内で循環参照が発生しないように注意する必要があります。
Java デザイン パターン プログラミングにおける責任連鎖パターンの適用を説明するその他の例については、PHP 中国語 Web サイトの関連記事に注目してください。