Définition : Permettre à plusieurs objets d'avoir la possibilité de traiter les requêtes, évitant ainsi la relation de couplage entre l'expéditeur et le destinataire de la requête. 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 de classe comportementale
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 gérera la requête. Si i==1, elle sera traitée par Handler1. i==2, il est géré par Handler2, et ainsi de suite. En programmation, cette méthode de traitement 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 les requêtes. 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 si simples. Déterminer s'il s'agit de 1 ou 2 peut nécessiter des calculs complexes, interroger la base de données, etc., ce qui nécessitera beaucoup de code supplémentaire. S'il y a plus de conditions de jugement, alors cette instruction if... else... ne fonctionnera fondamentalement pas. . Je l'ai vu.
Degré élevé de couplage : si nous voulons continuer à ajouter des classes pour le traitement des demandes, nous devons continuer à ajouter des conditions de jugement else if en plus, l'ordre de ce jugement de condition est également codé en dur. la commande, nous ne pouvons 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é.
La structure du modèle de chaîne de responsabilité
Le diagramme de classes du modèle de chaîne de responsabilité est très simple. Il se compose d'une classe de traitement abstrait et d'un ensemble de ses classes d'implémentation :
Traitement abstrait. classe : Dans la classe de traitement abstraite Elle comprend principalement une variable membre nextHandler qui pointe vers la classe de traitement suivante et une méthode handRequest pour traiter les requêtes. L'idée principale de la méthode handRequest est que si les conditions de traitement sont remplies, cette classe de traitement. le gérera, sinon il sera géré par nextHandler.
Classe de traitement spécifique : la classe de traitement spécifique implémente principalement une logique de traitement spécifique et des conditions applicables au traitement.
Exemple
Le modèle de chaîne de responsabilité a deux rôles :
Rôle de gestionnaire abstrait (Handler) : définit une interface demandée. Si nécessaire, vous pouvez définir une méthode pour définir et renvoyer une référence à l'objet suivant.
Rôle ConcreteHandler : si elle peut être traitée, la demande sera traitée. Si elle ne peut pas être traitée, la demande sera transmise à la partie suivante pour traitement. Cela signifie qu’il gère les demandes qu’il peut traiter et qu’il a accès à son prochain domicile.
Le code de test pour le mode ci-dessus est le suivant :
package chainOfResp; /** *描述:抽象处理角色 */ public abstract class Handler { protected Handler successor; /** *描述:处理方法 */ public abstract void handlerRequest(String condition); public Handler getSuccessor() { return successor; } public void setSuccessor(Handler successor) { this.successor = successor; } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandler1 extends Handler { @Override public void handlerRequest(String condition) { // 如果是自己的责任,就自己处理,负责传给下家处理 if(condition.equals("ConcreteHandler1")){ System.out.println( "ConcreteHandler1 handled "); return ; }else{ System.out.println( "ConcreteHandler1 passed "); getSuccessor().handlerRequest(condition); } } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandler2 extends Handler { @Override public void handlerRequest(String condition) { // 如果是自己的责任,就自己处理,负责传给下家处理 if(condition.equals("ConcreteHandler2")){ System.out.println( "ConcreteHandler2 handled "); return ; }else{ System.out.println( "ConcreteHandler2 passed "); getSuccessor().handlerRequest(condition); } } }
package chainOfResp; /** *描述:具体处理角色 */ public class ConcreteHandlerN extends Handler { /** * 这里假设n是链的最后一个节点必须处理掉 * 在实际情况下,可能出现环,或者是树形, * 这里并不一定是最后一个节点。 * */ @Override public void handlerRequest(String condition) { System.out.println( "ConcreteHandlerN handled"); } }
package chainOfResp; /** *描述:测试类 */ public class Client { /** *描述: */ public static void main(String[] args) { Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handlern = new ConcreteHandlerN(); //链起来 handler1.setSuccessor(handler2); handler2.setSuccessor(handlern); //假设这个请求是ConcreteHandler2的责任 handler1.handlerRequest("ConcreteHandler2"); } }
Pour donner un exemple, dans l'atelier de production d'une usine de jouets, la chaîne de montage C'est une chaîne de responsabilité. Par exemple, un avion jouet se compose d'un assembleur de coque, d'un assembleur de moteurs, d'un assembleur d'hélices et d'un emballeur de modèles. Lorsque cet objet sera transmis à qui que ce soit, il sera responsable de l'installation de la partie dont il est responsable. Une fois l'installation de cette partie terminée, il passera au lien suivant jusqu'à ce que tous les environnements soient terminés. Il s’agit d’une chaîne de responsabilité qui dure toute la vie. Il existe également une chaîne d'inspection de la qualité, et l'inspection de la qualité est également divisée en plusieurs parties, notamment l'inspection de la coque, l'inspection du moteur, l'inspection de l'hélice et l'inspection de l'emballage. Lorsque le produit est laissé à l'inspecteur pour qu'il inspecte la pièce dont il est responsable, s'il y a un problème, il sera récupéré directement. S'il n'y a pas de problème, il sera transmis à l'inspecteur suivant jusqu'à ce que toutes les inspections soient terminées. Les deux sont des chaînes de responsabilité, mais la différence est que chacun gérera la chaîne de responsabilité générée et en gérera une partie, tandis que la chaîne de responsabilité de l'inspection de la qualité sera jugée et traitée ou non. Ce sont les deux classifications des chaînes de responsabilité.La dernière est appelée chaîne de responsabilité pure, et la première est appelée chaîne de responsabilité impure.La chaîne de responsabilité pure existe rarement dans les applications pratiques, et la plus courante est la chaîne de responsabilité impure. est géré en simulant une pure chaîne de responsabilité.
Avantages et inconvénients du modèle de chaîne de responsabilité
Comparé à if...else..., le modèle de chaîne de responsabilité a un couplage plus faible car il distribue les déterminations de conditions dans différentes classes de traitement, et la priorité de ces classes de traitement. l'ordre peut être défini arbitrairement. 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 lorsque vous utilisez des instructions if...else... pour organiser une chaîne de responsabilité et que le code semble mauvais, vous pouvez utiliser le modèle de chaîne de responsabilité pour la reconstruction.
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. plus flexible, mais cela comporte également des risques. Par exemple, lors de la configuration des relations entre les classes de traitement, vous devez être particulièrement prudent pour déterminer la relation conditionnelle entre les classes logiques avant et après le traitement, et veiller à ne pas provoquer de références circulaires dans le chaîne.
Pour plus d'exemples expliquant l'application du modèle de chaîne de responsabilité dans la programmation de modèles de conception Java, veuillez faire attention au site Web PHP chinois pour les articles connexes !