ホームページ Java &#&チュートリアル Java デザイン パターン プログラミングにおける責任連鎖パターンの適用を説明する例

Java デザイン パターン プログラミングにおける責任連鎖パターンの適用を説明する例

Jan 19, 2017 pm 05:04 PM

定義: 複数のオブジェクトにリクエストを処理する機会を与えることで、リクエストの送信者と受信者の間の結合関係を回避します。これらのオブジェクトはチェーンに接続され、リクエストはオブジェクトが処理するまでチェーンに沿って渡されます。
タイプ: 動作パターン
クラス図:

Java デザイン パターン プログラミングにおける責任連鎖パターンの適用を説明する例

最初にコードを見てみましょう:

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 によって処理されるということです。 。
特定処理クラス: 特定処理クラスは主に特定の処理ロジックと処理に適用される条件を実装します。


責任連鎖パターンには 2 つの役割があります:

抽象ハンドラー (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 サイトの関連記事に注目してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? 会社のセキュリティソフトウェアはアプリケーションの実行に失敗していますか?それをトラブルシューティングと解決する方法は? Apr 19, 2025 pm 04:51 PM

一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? 名前を数値に変換してソートを実装し、グループの一貫性を維持するにはどうすればよいですか? Apr 19, 2025 pm 11:30 PM

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? MapsTructを使用したシステムドッキングのフィールドマッピングの問題を簡素化する方法は? Apr 19, 2025 pm 06:21 PM

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Intellijのアイデアは、ログを出力せずにSpring Bootプロジェクトのポート番号をどのように識別しますか? Apr 19, 2025 pm 11:45 PM

intellijideaultimatiateバージョンを使用してスプリングを開始します...

エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? エンティティクラス変数名をエレガントに取得して、データベースクエリ条件を構築する方法は? Apr 19, 2025 pm 11:42 PM

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

Javaオブジェクトを配列に安全に変換する方法は? Javaオブジェクトを配列に安全に変換する方法は? Apr 19, 2025 pm 11:33 PM

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Redisキャッシュソリューションを使用して、製品ランキングリストの要件を効率的に実現する方法は? Apr 19, 2025 pm 11:36 PM

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。

eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? eコマースプラットフォームSKUおよびSPUデータベースデザイン:ユーザー定義の属性と原因のない製品の両方を考慮する方法は? Apr 19, 2025 pm 11:27 PM

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

See all articles