2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Muster der Verantwortungskette: Vermeiden Sie die Kopplung von Anforderungssender und -empfänger, geben Sie mehreren Objekten die Möglichkeit, die Anforderung zu empfangen, verbinden Sie diese Objekte zu einer Kette und leiten Sie die Anforderung entlang dieser Kette weiter, bis ein Objekt zur Bearbeitung vorhanden ist.Das Chain-of-Responsibility-Modell ist aObjektverhaltensmuster。
Der Kern der Musterstruktur der Verantwortungskette ist die Einführung von aabstrakter Prozessor
Wie aus der Abbildung ersichtlich ist, enthält das Musterstrukturdiagramm der Verantwortungskette die folgenden zwei Rollen:
(1) Handler (abstrakter Handler): Er definiert eine Schnittstelle zur Verarbeitung von Anforderungen und ist im Allgemeinen als abstrakte Klasse konzipiert. Da verschiedene konkrete Handler Anforderungen unterschiedlich behandeln, sind in ihnen abstrakte Methoden zur Anforderungsbehandlung definiert.Da der untergeordnete Prozessor jedes Prozessors immer noch ein Prozessor ist, wird im abstrakten Prozessor ein Objekt vom Typ abstrakter Prozessor (Nachfolger im Strukturdiagramm) als untergeordneter Prozessor definiert.Zitat . Durch diese Referenz können Handler zu einer Kette verknüpft werden.
(2) ConcreteHandler (Betonhandler): Es ist eine Unterklasse des abstrakten Handlers und kann Benutzeranforderungen verarbeiten.Die im abstrakten Prozessor definierte Verarbeitungsmethode für abstrakte Anforderungen wird in der konkreten Prozessorklasse implementiert und kann auf das nächste zu erreichende Objekt in der Kette zugreifenWeiterleitung beantragenWirkung.
Im Chain of Responsibility-Muster werden die Verweise jedes Objekts auf seine Nachkommen zu einer Kette verbunden. Anfragen werden in dieser Kette nach oben weitergeleitet, bis das Objekt in der Kette die Anfrage schließlich bearbeitet. Dadurch kann das System die Kette dynamisch neu organisieren und Verantwortlichkeiten zuweisen, ohne den Client zu beeinträchtigen.
Der Kern des Verantwortungskettenmusters liegt im Design der abstrakten Handlerklasse. Der typische Code der abstrakten Handlerklasse lautet wie folgt:
abstract class Handler {
//维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(String request);
}
Im obigen Code definiert der abstrakte Prozessor ein Referenzobjekt für den nächsten Prozessor, um die Anfrage an den nächsten Prozessor weiterzuleiten. Der Accessor dieses Objekts kann auf „geschützt“ gesetzt werden, was in seinen Unterklassen verwendet werden kann.
Konkrete Handler sind Unterklassen abstrakter Handler und haben zwei Hauptfunktionen:
Typischer Code für eine bestimmte Handlerklasse lautet wie folgt:
class ConcreteHandler extends Handler {
public void handleRequest(String request) {
if (请求满足条件) {
//处理请求
}
else {
this.successor.handleRequest(request); //转发请求
}
}
}
Ein bestimmtes Bestellgenehmigungssystem ist hierarchisch, das heißt, es wird von Vorgesetzten auf verschiedenen Ebenen entsprechend dem Kaufbetrag genehmigt.
Der Direktor kann Bestellungen von weniger als 50.000 Yuan genehmigen, der stellvertretende Vorsitzende kann Bestellungen von [5.100.000 Yuan] genehmigen, der Vorstandsvorsitzende kann Bestellungen von [10.500.000 Yuan] und Bestellungen von 500.000 Yuan genehmigen und höher ist eine Vorstandssitzung zur Diskussion und Entscheidung erforderlich.
Da die Genehmiger jeder Position Untergebene haben (mit Ausnahme des Vorstands) und ihr Verhalten gleich ist, müssen sie alle Genehmigungen an ihre Nachfolger weiterleiten. Entwerfen Sie also eine Genehmigerklasse als abstrakten Prozessor:
//审批者类: 抽象处理者
abstract class Approver {
protected Approver successor; //定义后继对象
protected String name; //审批者姓名
public Approver(String name) {
this.name = name;
}
//设置后继者
public void setSuccessor(Approver successor) {
this.successor = successor;
}
public abstract void processRequest(PurchaseRequest request);
}
Dann muss jede Position als spezifischer Prozessor einen abstrakten Prozessor implementieren:
//主任: 具体处理者
class Director extends Approver{
public Director(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 50000) {
System.out.println(
MessageFormat.format("主任 {0} 审批采购单:{1}, 金额:{2}元, 采购目的:{3}。",
this.name, request.getNumber(), request.getAmount(), request.getPurpose())
);
} else {
this.successor.processRequest(request); //转发请求
}
}
}
//副董事长:具体处理类
class VicePresident extends Approver{
public VicePresident(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 100000) {
System.out.println(
MessageFormat.format("副董事长 {0} 审批采购单:{1}, 金额:{2}元, 采购目的:{3}。",
this.name, request.getNumber(), request.getAmount(), request.getPurpose())
);
} else {
this.successor.processRequest(request);
}
}
}
//董事长类:具体处理者
class President extends Approver{
public President(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < 500000) {
System.out.println(
MessageFormat.format("董事长 {0} 审批采购单:{1}, 金额:{2}元, 采购目的:{3}。",
this.name, request.getNumber(), request.getAmount(), request.getPurpose())
);
} else {
this.successor.processRequest(request);
}
}
}
//董事会类:具体处理者
class Congress extends Approver{
public Congress(String name) {
super(name);
}
@Override
public void processRequest(PurchaseRequest request) {
System.out.println(
MessageFormat.format("召开董事会 审批采购单:{0}, 金额:{1}元, 采购目的:{2}。",
request.getNumber(), request.getAmount(), request.getPurpose())
);
}
}
Definieren Sie eine andere Bestellkategorie als Ziel, das genehmigt werden muss:
//采购单: 请求类
class PurchaseRequest {
private double amount; //采购金额
private int number; //采购单编号
private String purpose; //采购目的
public PurchaseRequest(double amount, int number, String purpose) {
this.amount = amount;
this.number = number;
this.purpose = purpose;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPurpose() {
return purpose;
}
public void setPurpose(String purpose) {
this.purpose = purpose;
}
}
Schreiben Sie Client-Testcode:
class Client {
public static void main(String[] args) {
Approver kangXi, yongZheng, qianLong, hanLinYuan;
kangXi = new Director("康熙");
yongZheng = new VicePresident("雍正");
qianLong = new VicePresident("乾隆");
hanLinYuan = new Congress("翰林院");
//创建职责链
kangXi.setSuccessor(yongZheng);
yongZheng.setSuccessor(qianLong);
qianLong.setSuccessor(hanLinYuan);
//创建采购单
PurchaseRequest pr1 = new PurchaseRequest(45000, 10001, "购买刀");
kangXi.processRequest(pr1);
PurchaseRequest pr2 = new PurchaseRequest(60000, 10002, "购买枪");
kangXi.processRequest(pr2);
PurchaseRequest pr3 = new PurchaseRequest(160000, 10003, "购买火炮");
kangXi.processRequest(pr3);
PurchaseRequest pr4 = new PurchaseRequest(800000, 10004, "购买军舰");
kangXi.processRequest(pr4);
}
}
Kompilieren Sie das Programm und führen Sie es aus. Die Ausgabe lautet wie folgt:
主任 康熙 审批采购单:10,001, 金额:45,000元, 采购目的:购买刀。
副董事长 雍正 审批采购单:10,002, 金额:60,000元, 采购目的:购买枪。
董事长 乾隆 审批采购单:10,003, 金额:160,000元, 采购目的:购买火炮。
召开董事会 审批采购单:10,004, 金额:800,000元, 采购目的:购买军舰。
Lassen Sie uns einen Fall entwerfen, der sich geringfügig vom oben genannten unterscheidet und unser Verständnis des Chain-of-Responsibility-Modells und der Szenarien, in denen es angewendet werden kann, erweitern kann.
Die Schule weist der Klasse einige Aufgaben zur Bearbeitung zu. Zu diesen Aufgabentypen gehören eins, zwei, drei, vier usw. Der Klassenlehrer kann die drei Aufgabentypen eins, zwei, drei und der Monitor die beiden Aufgabentypen bearbeiten Eins, zwei. Das Lernkomitee kann eine dieser Aufgaben bearbeiten. Wenn der Klassenlehrer eine Aufgabe erhält, übergibt er diese zunächst dem Gruppenleiter zur Bearbeitung. Wenn die nächste Klasse sie nicht bewältigen kann, wird der Klassenlehrer sie selbst bearbeiten. Wenn der Klassenlehrer die Aufgabe erhält, übergibt er sie zuerst Wenn die nächste Klasse die Aufgabe nicht bewältigen kann, wird der Gruppenleiter die Aufgabe selbst erledigen. Und wenn sie damit nicht klarkommen, geben sie Feedback nach oben.
Die Handler-Klasse ist im Folgenden als abstrakter Prozessor konzipiert:
Da Sie und Ihre Untergebenen bestimmte Klassenaufgaben möglicherweise nicht unbedingt bewältigen können und es eine Rückmeldung nach oben gibt, muss die Anforderungsmethode des Prozessors einen booleschen Rückgabewert haben, um dem Vorgesetzten mitzuteilen, ob er die Aufgabe bewältigen kann.
abstract class Handler {
protected Handler successor; //定义后继对象
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract boolean handleRequest(String taskName);
}
Im Folgenden werden der Klassenlehrer, der Gruppenleiter und das Mitglied des Studienausschusses jeweils als spezifische Betreuer bezeichnet.
Standardmäßig übergibt der Klassenlehrer die Aufgabe zuerst an den Betreuer, und der Betreuer gibt die Aufgabe standardmäßig an das Studienausschussmitglied weiter. Das Studienausschussmitglied kann nur eine Art von Aufgaben bearbeiten, und wenn es diese nicht bearbeiten kann, dann diese wird false zurückgeben;
Wenn die vom Truppführer erhaltene Rückmeldung falsch ist, wird er sie selbst bearbeiten. Er kann nur eine oder zwei Aufgabentypen bearbeiten. Wenn er sie nicht bearbeiten kann, gibt er eine falsche Antwort zurück.
Wenn die Rückmeldung, die der Schulleiter erhält, falsch ist, wird er sie selbst bearbeiten. Er kann nur Aufgaben der Typen eins, zwei und drei bearbeiten. Wenn er die Aufgaben nicht bearbeiten kann, gibt er „falsch“ zurück.
//班主任
class HeadTeacher extends Handler{
@Override
public boolean handleRequest(String taskName) {
boolean handled = successor.handleRequest(taskName);
if (handled) {
return true;
}
if (taskName.equals("one") || taskName.equals("two") || taskName.equals("three")) {
System.out.println("班主任处理了该事务");
return true;
}
return false;
}
}
//班长
class Monitor extends Handler{
@Override
public boolean handleRequest(String taskName) {
boolean handled = successor.handleRequest(taskName);
if (handled) {
return true;
}
if (taskName.equals("one") || taskName.equals("two")) {
System.out.println("班长处理了该事务");
return true;
}
return false;
}
}
//学习委员
class StudyCommissary extends Handler{
@Override
public boolean handleRequest(String taskName) {
boolean handled;
if (successor == null) { //注意学习委员可能没有下家,所以这里判一下是否为空
handled = false;
} else {
handled = successor.handleRequest(taskName);
}
if (handled) {
return true;
}
if (taskName.equals("one")) {
System.out.println("学习委员处理了该事务");
return true;
}
return false;
}
}
Schreiben Sie Client-Testcode:
Richten Sie für jede Position Unterabteilungen ein. Beachten Sie jedoch, dass es keine Unterabteilung für die Mitglieder des Studienausschusses gibt.
Wenn es eine Aufgabe gibt, die der Schulleiter nicht bewältigen kann, drucken Sie außerdem eine Protokollzeile aus, um sie zu erläutern.
public class SchoolClient {
public static void main(String[] args) {
Handler headTeacher, monitor, studyCommissary;
headTeacher = new HeadTeacher();
monitor = new Monitor();
studyCommissary = new StudyCommissary();
headTeacher.setSuccessor(monitor);
monitor.setSuccessor(studyCommissary);
studyCommissary.setSuccessor(null); //没有下一职责人
startRequest(headTeacher, "one");
startRequest(headTeacher, "two");
startRequest(headTeacher, "three");
startRequest(headTeacher, "four");
}
private static void startRequest(Handler headTeacher, String taskName) {
if (! headTeacher.handleRequest(taskName)) {
System.out.println("该班级处理不了此类任务!");
}
}
}
Kompilieren Sie das Programm und führen Sie es aus. Die Ausgabe lautet wie folgt:
学习委员处理了该事务
班长处理了该事务
班主任处理了该事务
该班级处理不了此类任务!
Das Chain-of-Responsibility-Modell kann in den folgenden Situationen in Betracht gezogen werden:
Nachschlagewerke:
„Die Kunst der Designmuster“ – Liu Wei