前書き
責任の連鎖パターンにより、複数のオブジェクトが要求を処理する機会を得ることができるため、要求の送信者と受信者の間の結合関係を回避できます。これらのオブジェクトをチェーンに接続し、オブジェクトが処理するまでこのチェーンに沿ってリクエストを渡します。
インスタンス
責任の連鎖モデルには、次の役割が含まれます。
Handler
:抽象プロセッサ。リクエストを処理するためのインターフェースを定義します。必要に応じて、インターフェイスは次のホームへの参照を設定して返すメソッドを定義できます。この役割は通常、Java抽象クラスまたはJavaインターフェースによって実装されます。ConcreteHandler
:特定のプロセッサ。リクエストを受信した後、特定のプロセッサはリクエストを処理するか、次のパーティにリクエストを渡すかを選択できます。特定のプロセッサは次のホームへの参照を保持しているため、特定のプロセッサは必要に応じて次のホームにアクセスできます。Client
:カスタマークラス
以下では、例として休暇の簡単なリクエストを取り上げます。休暇を1日とすると、プロジェクトマネージャーが対応し、3日などはプロジェクトディレクターが担当し、7日以内は上司が担当し、7日を超えることはできません。抽象ハンドラー
public abstract class AbstractHandler {
/**
* 下一个处理对象
*/
private AbstractHandler next;
/**
* 处理请假
*
* @param leaveDays 天数
* @return 处理结果
*/
public final String handleLeave(int leaveDays) {
if (this.getLeaveDays() >= leaveDays) {
return this.handle();
} else {
if (Objects.nonNull(next)) {
return next.handleLeave(leaveDays);
} else {
return "大老板都不能处理你的假期了~~";
}
}
}
/**
* 具体处理
*
* @return 处理结果
*/
protected abstract String handle();
/**
* 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了
*
* @return 请假天数
*/
protected abstract Integer getLeaveDays();
/**
* 设置下一个处理类
*
* @param next
*/
public void setNext(AbstractHandler next) {
this.next = next;
}
}
特定のハンドラー
// 项目经理处理
public class PMHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被项目经理处理了";
}
@Override
protected Integer getLeaveDays() {
return 1;
}
}
// 项目总监处理
public class PDHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被项目总监处理了";
}
@Override
protected Integer getLeaveDays() {
return 3;
}
}
// 大老板处理
public class BossHandler extends AbstractHandler {
@Override
protected String handle() {
return "你的请假被大老板处理了";
}
@Override
protected Integer getLeaveDays() {
return 7;
}
}
クライアント
@Test
public void test() {
PMHandler pmHandler = new PMHandler();
PDHandler pdHandler = new PDHandler();
BossHandler bossHandler = new BossHandler();
pmHandler.setNext(pdHandler);
pdHandler.setNext(bossHandler);
String leaveRes = pmHandler.handleLeave(1);
System.out.println(leaveRes);
String leaveRes1 = pmHandler.handleLeave(3);
System.out.println(leaveRes1);
String leaveRes2 = pmHandler.handleLeave(7);
System.out.println(leaveRes2);
String leaveRes3 = pmHandler.handleLeave(8);
System.out.println(leaveRes3);
}
クラス図
利点
- カップリングを減らします。リクエストの送信者と受信者を切り離します。
- オブジェクトを簡略化しました。そのため、オブジェクトはチェーンの構造を知る必要がありません。
- オブジェクトに責任を割り当てる際の柔軟性を高めます。チェーンのメンバーを変更したり、順序を動員したりすることで、責任を動的に追加または削除できます。
- 新しいリクエスト処理クラスを追加すると便利です。
不利益
- リクエストには明確な受信者がなく、処理される保証はありません。リクエストはチェーンの最後まで処理されない場合があります。
- 責任の連鎖が比較的長い場合、要求の処理には複数の処理オブジェクトが含まれる可能性があり、システムパフォーマンスにある程度の影響があり、コードのデバッグが不便であり、ループ呼び出しが発生する可能性があります。
該当シーン
- 同じリクエストを処理できるオブジェクトは複数あり、リクエストを処理するオブジェクトは実行時に自動的に決定されます。
- 受信者を明確に指定せずに、複数のオブジェクトの1つにリクエストを送信します。
- オブジェクトのグループは、要求を処理するために動的に指定できます。
総括する
責任の連鎖モデルの使用には、純粋な責任の連鎖モデルと不純な責任の連鎖モデルの2つの形式があります。
クラスがリクエストの処理または次のボールへのリクエストのキックを担当する場合、それは純粋な責任チェーンモデルと呼ばれます。クラスが責任の一部を引き受け、次のボールのキックも要求する場合、それは不純と呼ばれます。責任の連鎖モデル。純粋な責任連鎖モデルの実際的な例を見つけることは困難であり、一般的に見られる例は、不純な責任連鎖モデルの実現です。