Définition: permet à plusieurs objets d'avoir la possibilité de traiter la demande, évitant ainsi la relation de couplage entre l'expéditeur et le récepteur de la demande. Connectez ces objets dans une chaîne et passez la demande le long de la chaîne jusqu'à ce qu'un objet le traite.
Type: modèle de comportement
Diagramme de classe:
Regardons d'abord un morceau de code:
Public void test (int i, demande de demande) {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); }} La logique métier du code est la suivante: La méthode a deux paramètres: l'integer I et une demande de demande. Selon la valeur de I, qui gérera la demande, si i == 1, elle sera gérée par Handler1, si i == 2, elle sera gérée par Handler2, etc. En programmation, ce type de méthode de traitement commercial est très courant. Toutes les classes que les demandes de processus incluent si ... else ... Instructions de jugement conditionnel liées à une chaîne de responsabilité pour traiter la demande. Je crois que tout le monde l'utilise souvent. Les avantages de cette méthode sont qu'il est très intuitif, simple et clair et relativement facile à entretenir, mais cette méthode a également plusieurs maux de tête:
Code gonflé: Dans les applications réelles, les conditions de jugement ne sont généralement pas si simples pour déterminer si elle est 1 ou 2. Cela peut nécessiter des calculs complexes, peut-être interroger la base de données, etc. Cela aura beaucoup de code supplémentaire. S'il y a de nombreuses conditions de jugement, alors si ... sinon ... la déclaration est fondamentalement impossible à lire.
Degré de couplage élevé: si nous voulons continuer à ajouter des classes qui demandent le processus, nous devons continuer à ajouter d'autre si les conditions de jugement; De plus, l'ordre de cette condition est également écrit aux morts. Si nous voulons modifier la commande, nous ne pouvons modifier cette instruction de cette condition.
Comme nous avons déjà compris les lacunes, nous devons trouver un moyen de les résoudre. La logique métier de ce scénario est très simple: si la condition 1 est remplie, elle sera traitée par Handler1, et si elle n'est pas remplie, elle sera transmise; Si la condition 2 est remplie, elle sera traitée par Handler2, et si elle n'est pas remplie, elle sera transmise, et ainsi de suite jusqu'à la fin de la condition. En fait, la méthode d'amélioration est également très simple, c'est-à-dire de mettre la partie des conditions de jugement dans la classe de traitement. Il s'agit du principe du modèle de connexion de la responsabilité.
La structure du modèle de société de responsabilité
Le diagramme de classe du modèle connecté à la responsabilité est très simple, il se compose d'une classe traitée abstraitement et de son ensemble de classes d'implémentation:
Résumé Classe de traitement: la classe de traitement abstraite comprend principalement une variable de membre Nexthandler pointant vers la prochaine classe de traitement et une méthode HandRequest qui gère la demande. L'idée principale de la méthode HandRequest est que si les conditions de traitement sont remplies, cette classe de traitement sera traitée, sinon elle sera traitée par Nexthandler.
Classe de traitement spécifique: la classe de traitement spécifique implémente principalement la logique de traitement spécifique et les conditions applicables pour le traitement.
Exemple
Le modèle de la chaîne de responsabilité a deux rôles:
Rôle du gestionnaire abstrait: définit une interface demandée. Si nécessaire, vous pouvez définir une méthode pour définir et retourner la référence à l'objet domestique suivant.
Rôle du béton: s'il peut être traité, traitez la demande. S'il ne peut pas être traité, passez la demande à la maison suivante et laissez la maison suivante le gérer. C'est-à-dire qu'il gère les demandes qu'il peut gérer et peut accéder à sa prochaine maison.
Le code de test pour le modèle ci-dessus est le suivant:
Package ChainofResp; / ** * Description: Rôle de traitement abstrait * / Public Résumé Handler {Protected Handler Successeur; / ** * Description: Méthode de traitement * / Public Résumé void handlerRequest (condition de chaîne); Public Handler getUCCessor () {return successeur; } public void setSuccesseur (Handler successeur) {this.successor = successeur; }} Package ChainofResp; / ** * Description: Gestionnement détaillé des rôles * / classe publique ConcreteHandler1 étend le gestionnaire {@Override public void handlerRequest (String Condition) {// Si c'est votre propre responsabilité, vous le gérerez vous-même et sera responsable de la transmission à la prochaine maison si (condition.equals ("Concretehandler")) {System.out.out.TratLn ("Conscrite1"); retour ; } else {System.out.println ("ConcreteHandler1 passé"); getSuccessor (). handlerRequest (condition); }}} Package ChainofResp; / ** * Description: Gestionnement détaillé des rôles * / classe publique ConcreteHandler2 étend le gestionnaire {@Override public void handlerRequest (String Condition) {// Si c'est votre propre responsabilité, vous le gérerez vous-même et sera responsable de la transmission à la prochaine maison si (condition.equals ("ConcreteHandler2")) {System.out.out.out.Println ("Conscrite2"); retour ; } else {System.out.println ("ConcreteHandler2 passé"); getSuccessor (). handlerRequest (condition); }}} Package ChainofResp; / ** * Description: Rôle de traitement détaillé * / classe publique ConcreteHandlern étend le gestionnaire {/ ** * Ici, il est supposé que N est le dernier nœud de la chaîne qui doit être traité * dans les situations réelles, un anneau ou un arbre peut apparaître, * Ce n'est pas nécessairement le dernier nœud. * * / @Override public void handlerRequest (String Condition) {System.out.println ("ConcreteHandlern Greatled"); }} package chainofresp; / ** * Description: Classe de test * / classe publique Client {/ ** * Description: * / public static void main (String [] args) {handler handler1 = new ConcreteHandler1 (); Handler Handler2 = new ConcreteHandler2 (); Handler Handlern = new ConcreteHandlern (); // Chain Handler1.SetSuccessor (Handler2); Handler2.SetSuccessor (Handlern); // Supposons que cette demande soit la responsabilité de ConcreteHandler2 Handler1.HandlerRequest ("ConcreteHandler2"); }}
Pour donner cet exemple, dans l'atelier de production d'une usine de jouets, la chaîne de montage est une chaîne de responsabilités. Si un avion jouet a un assembleur à coque, un assembleur de moteur, un assembleur d'hélice et un emballeur de modèle. Lorsque l'avion coule vers qui que l'objet coule, il sera responsable de l'installation de la pièce dont il est responsable. Une fois cette pièce installée, elle passera à l'étape suivante et sait que tous les environnements sont terminés. Il s'agit d'une chaîne de responsabilité générée. Il existe également une chaîne d'inspection de qualité, qui est divisée en plusieurs parties, inspection des coquilles, inspection du moteur, inspection de l'hélice et inspection des emballages. Lorsque le produit est laissé à l'inspecteur pour tester la pièce dont il est responsable, s'il y a un problème, il sera directement retiré. S'il n'y a pas de problème, il sera transmis à l'inspecteur suivant jusqu'à ce que tous les tests soient terminés. Ces deux sont des chaînes de responsabilités, mais la différence est que chacun traitera la chaîne de responsabilités et le fait partie de celui-ci; Bien qu'après le jugement, la chaîne de responsabilité pour l'inspection de la qualité sera soit traitée ou non traitée. Ce sont les deux catégories de chaînes de responsabilité. Ce dernier est appelé des chaînes de responsabilité pure, et le premier est appelé des chaînes de responsabilité impurs. Les chaînes de responsabilité pures existent rarement dans des applications pratiques. Le commun est des chaînes de responsabilité impures. Le modèle ci-dessus simule les chaînes de responsabilité pure à gérer.
Avantages et inconvénients du modèle de chaîne de responsabilité
Par rapport à If… else…, le modèle de chaîne de responsabilité a une capacité de couplage plus faible car elle distribue les jugements conditionnels dans diverses classes de traitement, et l'ordre de traitement prioritaire de ces classes de traitement peut être défini à volonté. Le modèle de chaîne de responsabilité a également ses inconvénients, qui sont les mêmes que la déclaration if ... else ..., c'est-à-dire avant de trouver la classe de traitement correcte, toutes les conditions de jugement doivent être exécutées. Lorsque la chaîne de responsabilités est relativement longue, le problème de performance est plus grave.
Scénarios applicables pour le modèle de la chaîne de responsabilité
Tout comme l'exemple de début, si vous vous sentez dépassé lorsque vous utilisez la déclaration if… else… pour organiser une chaîne de responsabilités et que le code semble mauvais, vous pouvez utiliser le mode chaîne de responsabilité pour le refacter.
Résumer
Le modèle de chaîne de responsabilité est en fait une version flexible de la déclaration if ... else ... Il met ces conditions de jugement dans chaque classe de traitement. L'avantage de cela est qu'il est plus flexible, mais il entraîne également des risques. Par exemple, lors de la mise en place de la relation entre la classe de traitement avant et après la classe de traitement, vous devez faire très attention à juger la relation entre la logique conditionnelle avant et après la classe de traitement, et veillez à ne pas avoir de références circulaires dans la chaîne.