23 Modèles de conception Chapitre 19: modèle de chaîne de responsabilité Java
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 la chaîne de responsabilité
Le diagramme de classe du modèle de la chaîne de 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.
Après avoir compris l'idée générale du modèle de chaîne de responsabilité, il sera plus facile de comprendre en regardant le code:
classe de classe {private int niveau = 0; Niveau public (niveau int) {this.level = niveau; }; public boolean ci-dessus (niveau de niveau) {if (this.level> = niveau.level) {return true; } return false; }} demande de classe {niveau de niveau; Demande publique (niveau de niveau) {this.level = niveau; } public Niveau GetLevel () {NIVEAU RETOUR; }} Réponse de classe {} Résumé Handler de classe {Handler privé NexThandler; Public Final Response HandleRequest (demande de demande) {Response Response = NULL; if (this.gethandlerlevel (). ci-dessus (request.getLevel ())) {réponse = this.Response (request); } else {if (this.nexthandler! = null) {this.nexthandler.handleRequest (request); } else {System.out.println ("----------"); }} Retour Response; } public void SetNExThandler (Handler Handler) {this.nexthandler = handler; } Niveau abstrait protégé Gethandlerlevel (); Réponse abstraite du public (demande de demande); } classe ConcreteHandler1 étend Handler {Niveau protégé Gethandlerlevel () {return new Level (1); } Réponse de réponse publique (demande de demande) { System.out.println("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ class ConcreteHandler2 étend le gestionnaire {le niveau protégé Gethandlerlevel () {return net (3);} Réponse publique (demande de demande) {System.out.println ("--------------"); System.out.println (------ Les demandes sont traitées par le processeur 3 ----- "); handler1.setNExThandler (Handler2);Dans le code, la classe de niveau simule les conditions de détermination; La demande et la réponse correspondent respectivement aux demandes et aux réponses; Le gestionnaire de classe abstrait juge principalement les conditions et un niveau de traitement est simulé ici. Seul le niveau de traitement de la classe de traitement est supérieur au niveau de la demande peut être traité, sinon il sera remis au prochain processeur pour le traitement.
Définissez la relation d'exécution avant et arrière de la chaîne dans la classe client et remettez la demande à la première classe de traitement pendant l'exécution. Il s'agit du modèle de chaîne de responsabilité. La fonction qu'il complète est la même que la déclaration if ... else ... dans l'article précédent.
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.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.