mes coordonnées
Mailmesophia@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Modèle de chaîne de responsabilité : évitez de coupler l'expéditeur et le destinataire de la demande, donnez à plusieurs objets la possibilité de recevoir la demande, connectez ces objets dans une chaîne et transmettez la demande le long de cette chaîne jusqu'à ce qu'il y ait un objet pour la gérer.Le modèle de chaîne de responsabilité est unmodèle de comportement d'un objet。
Le cœur de la structure du modèle de chaîne de responsabilité est l’introduction d’unprocesseur abstrait
Comme le montre la figure, le diagramme de structure du modèle de chaîne de responsabilité contient les deux rôles suivants :
(1) Gestionnaire (gestionnaire abstrait) : il définit une interface de traitement des requêtes et est généralement conçu comme une classe abstraite. Étant donné que différents gestionnaires concrets gèrent les requêtes différemment, des méthodes abstraites de gestion des requêtes y sont définies.Étant donné que le subordonné de chaque processeur est toujours un processeur, un objet de type processeur abstrait (successeur dans le diagramme de structure) est défini dans le processeur abstrait comme son subordonné.Citation . Grâce à cette référence, les gestionnaires peuvent être liés en une chaîne.
(2) ConcreteHandler (gestionnaire concret) : il s'agit d'une sous-classe de gestionnaire abstrait et peut gérer les demandes des utilisateurs.La méthode de traitement des requêtes abstraites définie dans le processeur abstrait est implémentée dans la classe de processeur concrète et peut accéder à l'objet suivant de la chaîne pour réaliserDemande de transfertEffet.
Dans le modèle Chaîne de responsabilité, les références de chaque objet à ses descendants sont connectées pour former une chaîne. Les demandes sont transmises dans cette chaîne jusqu'à ce que l'objet de la chaîne traite finalement la demande. Cela permet au système de réorganiser dynamiquement la chaîne et d'attribuer des responsabilités sans affecter le client.
Le cœur du modèle de chaîne de responsabilité réside dans la conception de la classe de gestionnaire abstrait. Le code typique de la classe de gestionnaire abstrait est le suivant :
abstract class Handler {
//维持对下家的引用
protected Handler successor;
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract void handleRequest(String request);
}
Dans le code ci-dessus, le processeur abstrait définit un objet de référence au processeur suivant afin de transmettre la requête au processeur suivant. L'accesseur de cet objet peut être défini sur protected, qui peut être utilisé dans ses sous-classes.
Les gestionnaires concrets sont des sous-classes de gestionnaires abstraits et ont deux fonctions principales :
Le code typique pour une classe de gestionnaire spécifique est le suivant :
class ConcreteHandler extends Handler {
public void handleRequest(String request) {
if (请求满足条件) {
//处理请求
}
else {
this.successor.handleRequest(request); //转发请求
}
}
}
Un certain système d'approbation des bons de commande est hiérarchique, c'est-à-dire qu'il est approuvé par des superviseurs à différents niveaux en fonction du montant de l'achat.
Le directeur peut approuver des bons de commande de moins de 50 000 yuans, le vice-président peut approuver des bons de commande de [5 100 000 yuans], le président du conseil d'administration peut approuver des bons de commande de [10 500 000 yuans] et des bons de commande de 500 000 yuans. et au-dessus. Une réunion du conseil d’administration est nécessaire pour discuter et décider.
Étant donné que les approbateurs de chaque poste ont des subordonnés (à l'exception du conseil d'administration) et que leurs comportements sont communs, ils impliquent tous de transmettre des approbations à leurs successeurs. Concevez donc une classe d'approbateur en tant que processeur abstrait :
//审批者类: 抽象处理者
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);
}
Ensuite chaque poste, en tant que processeur spécifique, doit implémenter un processeur abstrait :
//主任: 具体处理者
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())
);
}
}
Définissez une autre catégorie de bon de commande comme cible qui doit être approuvée :
//采购单: 请求类
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;
}
}
Écrivez le code de test client :
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);
}
}
Compilez et exécutez le programme, le résultat est le suivant :
主任 康熙 审批采购单:10,001, 金额:45,000元, 采购目的:购买刀。
副董事长 雍正 审批采购单:10,002, 金额:60,000元, 采购目的:购买枪。
董事长 乾隆 审批采购单:10,003, 金额:160,000元, 采购目的:购买火炮。
召开董事会 审批采购单:10,004, 金额:800,000元, 采购目的:购买军舰。
Concevons un cas légèrement différent de celui ci-dessus, qui peut élargir notre compréhension du modèle de chaîne de responsabilité et des scénarios dans lesquels il peut être appliqué.
L'école attribuera certaines tâches à la classe pour traitement. Ces types incluent une, deux, trois, quatre, etc. L'enseignant de la classe peut gérer les trois types de tâches un, deux, trois et le moniteur peut gérer les deux types de tâches. un, deux. Tâches, le comité d'apprentissage peut gérer un de ce type de tâches. Lorsque l'enseignant de la classe reçoit une tâche, il la remettra d'abord au chef d'équipe pour traitement. Si la classe suivante ne peut pas la gérer, l'enseignant de la classe la gérera lui-même. Lorsque l'enseignant de la classe recevra la tâche, il la confiera en premier. au comité d'école pour traitement. Si la classe suivante ne peut pas s'en occuper, l'enseignant de la classe le fera. Le chef d'équipe s'en chargera lui-même lorsque le comité d'école recevra une tâche, il la gérera lui-même s'il le peut ; Et quand ils ne peuvent pas le gérer, ils donneront un feedback vers le haut.
La classe Handler est conçue ci-dessous comme un processeur abstrait :
Étant donné que vous et vos subordonnés n'êtes pas nécessairement capables de gérer certaines tâches de classe et qu'il y a un retour d'information ascendant, la méthode de requête du processeur doit avoir une valeur de retour booléenne pour indiquer au supérieur s'il peut gérer la tâche.
abstract class Handler {
protected Handler successor; //定义后继对象
public void setSuccessor(Handler successor) {
this.successor = successor;
}
public abstract boolean handleRequest(String taskName);
}
Ci-dessous, l'enseignant de la classe, le chef d'équipe et le membre du comité d'étude sont respectivement conçus comme des gestionnaires spécifiques.
Par défaut, l'enseignant de la classe confiera d'abord la tâche au chef d'équipe, et le chef d'équipe confiera la tâche au membre du comité d'étude par défaut. Le membre du comité d'étude ne peut gérer qu'un seul type de tâches, et s'il ne peut pas le gérer. , il retournera false ;
Si le retour reçu par le chef d'équipe est faux, il le gérera lui-même. Il ne peut gérer qu'un ou deux types de tâches. S'il ne peut pas le gérer, il retournera faux.
Si le retour reçu par le directeur est faux, il le gérera lui-même. Il ne peut gérer que les tâches d'un, deux et trois types. S'il ne peut pas gérer les tâches, il retournera faux.
//班主任
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;
}
}
Écrivez le code de test client :
Créez des sous-maisons pour chaque poste, mais notez qu'il n'y a pas de sous-maison pour les membres des comités d'étude.
De plus, s’il y a une tâche que le directeur ne peut pas gérer, imprimez une ligne de journal pour l’expliquer.
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("该班级处理不了此类任务!");
}
}
}
Compilez et exécutez le programme, le résultat est le suivant :
学习委员处理了该事务
班长处理了该事务
班主任处理了该事务
该班级处理不了此类任务!
Le modèle de chaîne de responsabilité peut être envisagé dans les situations suivantes :
Livres de référence:
"L'art des modèles de conception" - Liu Wei