Cet article présente principalement en détail les informations pertinentes sur le modèle de conception et le modèle de chaîne de responsabilité. Il a une certaine valeur de référence. Les amis intéressés peuvent se référer à
Définition : Donner plusieurs. aux objets une chance de traiter la demande, évitant ainsi la relation de couplage entre l'expéditeur et le destinataire de la demande. Ces objets sont connectés dans une chaîne et la requête est transmise le long de la chaîne jusqu'à ce qu'un objet la gère.
Type : Modèle comportemental
Diagramme de classes :
Premier aperçu d'un morceau de code :
public void test(int i, Request request){ 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 : un entier i et une requête La valeur de i détermine qui va gérer. la requête. , si i==1, elle sera traitée par Handler1, si i==2, elle sera traitée par Handler2, et ainsi de suite. En programmation, cette méthode de gestion des affaires est très courante. Toutes les classes qui gèrent les requêtes ont des instructions de jugement conditionnel if...else... connectées pour former une chaîne de responsabilité pour traiter la requête. Je pense que tout le monde l'utilise souvent. L'avantage de cette méthode est qu'elle est très intuitive, simple et claire, et relativement facile à maintenir. Cependant, cette méthode présente également plusieurs problèmes gênants :
code gonflé : Les conditions de jugement dans les applications réelles ne sont généralement pas aussi simples que de juger si c'est 1 ou 2. Cela peut nécessiter des calculs complexes, des interrogations de la base de données, etc., ce qui nécessitera beaucoup de code supplémentaire. il y a trop de conditions de jugement, alors cette déclaration if...else... est fondamentalement illisible.
Couplage élevé : Si nous voulons continuer à ajouter des classes pour le traitement des requêtes, alors nous devons continuer à ajouter else if conditions de jugement en plus, l'ordre de ce jugement de condition ; est également codé en dur, si vous souhaitez modifier l'ordre, vous ne pouvez modifier que cette instruction conditionnelle.
Maintenant que nous sommes conscients des lacunes, nous devons trouver des moyens 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, sinon, elle sera transmise ; si la condition 2 est remplie, elle sera traitée par Handler2, si elle n'est pas remplie ; , il continuera à être transmis, et ainsi de suite, jusqu'à ce que la condition prenne fin. En fait, la méthode d'amélioration est également très simple, qui consiste à placer la partie condition de jugement dans la classe de traitement. C'est le principe du modèle de chaîne de responsabilité.
Structure du modèle Chaîne de Responsabilité
Le diagramme de classes du modèle Chaîne de Responsabilité est très simple, il consiste en une abstraction qui gère une classe et son ensemble de composition de classe d'implémentation :
Classe de traitement abstrait : La classe de traitement abstrait comprend principalement une variable membre nextHandler qui pointe vers le classe de traitement suivante et une méthode de demande de traitement handRequest, l'idée principale de la méthode handRequest est que si les conditions de traitement sont remplies, cette classe de traitement la gérera, sinon elle sera gérée par nextHandler.
Classe de traitement spécifique : La classe de traitement spécifique implémente principalement une logique de traitement spécifique et les conditions applicables au traitement.
Après avoir compris l'idée générale du modèle de chaîne de responsabilité, elle est plus facile à comprendre quand on regarde le code :
class Level { private int level = 0; public Level(int level){ this.level = level; }; public boolean above(Level level){ if(this.level >= level.level){ return true; } return false; } } class Request { Level level; public Request(Level level){ this.level = level; } public Level getLevel(){ return level; } } class Response { } abstract class Handler { private Handler nextHandler; public final Response handleRequest(Request request){ Response response = null; if(this.getHandlerLevel().above(request.getLevel())){ response = this.response(request); }else{ if(this.nextHandler != null){ this.nextHandler.handleRequest(request); }else{ System.out.println("-----没有合适的处理器-----"); } } return response; } public void setNextHandler(Handler handler){ this.nextHandler = handler; } protected abstract Level getHandlerLevel(); public abstract Response response(Request request); } class ConcreteHandler1 extends Handler { protected Level getHandlerLevel() { return new Level(1); } public Response response(Request request) { System.out.println("-----请求由处理器1进行处理-----"); return null; } } class ConcreteHandler2 extends Handler { protected Level getHandlerLevel() { return new Level(3); } public Response response(Request request) { System.out.println("-----请求由处理器2进行处理-----"); return null; } } class ConcreteHandler3 extends Handler { protected Level getHandlerLevel() { return new Level(5); } public Response response(Request request) { System.out.println("-----请求由处理器3进行处理-----"); return null; } } public class Client { public static void main(String[] args){ Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); handler1.setNextHandler(handler2); handler2.setNextHandler(handler3); Response response = handler1.handleRequest(new Request(new Level(4))); } }
Classe de niveau dans le code Il s'agit d'une condition de jugement simulée ; Requête et Réponse correspondent respectivement aux requêtes et aux réponses ; la classe abstraite Handler effectue principalement un jugement de condition Ici, seul le niveau de traitement de la classe de traitement est simulé. supérieur au niveau de la demande peut être traité, sinon il sera transmis au traitement ou au traitement suivant. Définissez la relation de la chaîne avant et après l'exécution dans la classe Client et transmettez la demande à la première classe de traitement pendant l'exécution. Il s'agit du mode de chaîne de responsabilité. La fonction qu'elle remplit est la même que l'instruction if...else.... dans l'article précédent.
Avantages et inconvénients du modèle de chaîne de responsabilité
En comparaison avec if...else..., le modèle de chaîne de responsabilité a un couplage plus faible car Il répartit les jugements conditionnels dans diverses classes de traitement, et l'ordre de priorité de traitement de ces classes de traitement peut être défini à volonté. Le modèle de chaîne de responsabilité présente également des défauts, qui sont les mêmes que ceux des instructions if...else..., c'est-à-dire que toutes les conditions de jugement doivent être exécutées avant que la classe de traitement correcte ne soit trouvée. relativement longue, les problèmes de performances sont plus graves.
Scénarios applicables du modèle de chaîne de responsabilité
Tout comme l'exemple initial, si vous vous sentez inadéquat lors de l'utilisation des instructions if...else... pour organiser une chaîne de responsabilité, lorsque votre code semble mauvais, utilisez le modèle de chaîne de responsabilité pour le refactoriser.
Résumé
Le modèle de chaîne de responsabilité est en fait une version flexible de l'instruction if...else.... Il place ces instructions de condition de jugement dans chaque classe de traitement. L'avantage est qu'il est plus flexible, mais aussi. comporte des risques.Par exemple, lors de la configuration de la relation entre les classes de traitement, vous devez être particulièrement prudent pour déterminer la relation conditionnelle entre la logique avant et après les classes de traitement, et veiller à ne pas provoquer de références circulaires dans la chaîne.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!