23 Modèles de conception Chapitre 16: Modèle de visiteur Java
Définition: résume certaines opérations qui agissent sur chaque élément d'une certaine structure de données. Il peut définir de nouvelles opérations qui agissent sur ces éléments sans modifier la structure des données.
Type: modèle de comportement
Diagramme de classe:
Le mode des visiteurs peut être le mode le plus complexe parmi les modes comportementaux, mais cela ne peut pas être une raison pour laquelle nous ne le maîtrisons pas.
Regardons d'abord un exemple simple, le code est le suivant
classe A {public void method1 () {System.out.println ("Je suis un"); } public void method2 (b b) {b.showa (this); }} classe b {public void showa (a a) {a.method1 (); }}Examinons principalement quelle est la différence entre la méthode Méthode1 et la méthode Méthode 2 dans la classe A. Méthode Method1 est très simple, il suffit d'imprimer une phrase "Je suis un"; Méthode Method2 est un peu plus compliquée, utilisez la classe B comme paramètre et appelez la méthode de la classe B.
Jetons un coup d'œil à la méthode Showa de la classe B. La méthode de showa utilise la classe A comme paramètre, puis appelle la méthode Méthode1 de la classe A. Vous pouvez voir que la méthode Method2 appelle simplement sa propre méthode Method1. Son résultat de course devrait également être "Je suis un". Après l'analyse, exécutons ces deux méthodes et voyons le résultat de l'exécution:
Classe publique Test {public static void main (String [] args) {a a = new a (); a.Method1 (); a.Method2 (new B ()); }}Le résultat en cours est:
Je suis un
Je suis un
Après avoir compris cet exemple, vous comprendrez 90% du modèle des visiteurs. Dans l'exemple, pour la classe A, la classe B est un visiteur. Cependant, cet exemple n'est pas l'ensemble du mode visiteur. Bien qu'il soit intuitif, il a une mauvaise évolutivité. Parlons de la mise en œuvre générale du mode visiteur. Vous pouvez voir à travers le diagramme de classe que dans le mode visiteur, les rôles suivants sont principalement inclus:
Visiteur abstrait: une classe ou une interface abstraite qui déclare les éléments auxquels le visiteur peut accéder. Plus précisément dans le programme, les paramètres de la méthode de visite définissent les objets accessibles.
Visiteur: Mettez en œuvre la méthode déclarée par les visiteurs abstraits, ce qui affecte ce que les visiteurs doivent faire et ce qu'ils doivent faire après avoir accédé à une classe.
Classe d'éléments abstraite: une interface ou une classe abstraite qui déclare le type d'accès aux visiteurs acceptée. Le programme est défini à travers des paramètres dans la méthode d'acceptation. Il existe généralement deux types de méthodes pour les éléments abstraits, l'un est sa propre logique commerciale, et l'autre est le type de visiteurs qui est autorisé à accéder.
Classe d'éléments: implémente la méthode d'acceptation déclarée par la classe d'éléments abstraites, généralement Visitor.Visit (ceci), et a essentiellement formé une formule fixe.
Objet structurel: Un conteneur d'élément contient généralement un conteneur qui s'adapte à plusieurs classes et interfaces différentes, telles que la liste, le set, la carte, etc. Ce rôle est rarement abstrait dans le projet.
Implémentation du code commun du mode visiteur
Élément de classe abstrait {public abstrait vide accepter (visiteur ivisitor); abstrait vide dosomething (); } Interface iVisitor {public void Visit (ConcreteElement1 El1); Visite de vide publique (ConcreteElement2 EL2); } classe ConcreteElement1 étend l'élément {public void dosomething () {System.out.println ("Ceci est l'élément 1"); } public void accepter (Ivisitor Visitor) {Visitor.Visit (this); }} classe ConcreteElement2 étend l'élément {public void dosomething () {System.out.println ("Ceci est l'élément 2"); } public void accepter (Ivisitor Visitor) {Visitor.Visit (this); }} Classe Le visiteur implémente ivisitor {public void Visit (ConcreteElement1 el1) {el1.doSomething (); } Public Void Visit (ConcreteElement2 El2) {el2.doSomething (); }} class objectStruture {public static list <element> getList () {list <element> list = new ArrayList <element> (); Random ran = nouveau aléatoire (); pour (int i = 0; i <10; i ++) {int a = ran.nextint (100); if (a> 50) {list.add (new ConcreteElement1 ()); } else {list.add (new ConcreteElement2 ()); }} Retour List; }} public class Client {public static void main (String [] args) {list <element> list = objectstruture.getList (); pour (élément e: list) {E.Accept (new Visitor ()); }}} Avantages du mode visiteur
Respectez le principe de responsabilité unique: dans tout scénario où le mode visiteur est applicable, les opérations qui doivent être encapsulées chez le visiteur dans la classe d'éléments doivent être des opérations qui ont peu à voir avec la classe d'éléments elle-même et sont volatiles. D'une part, l'utilisation du mode visiteur est conforme au principe de responsabilité unique, et d'autre part, car les opérations encapsulées sont généralement volatiles, lorsque des changements se produisent, l'expansion de la partie changeante peut être réalisée sans modifier la classe d'élément elle-même.
Bonne évolutivité: les classes d'éléments peuvent étendre différentes opérations en acceptant différents visiteurs.
Scénarios applicables pour le mode visiteur
S'il existe des opérations dans un objet qui ne sont pas liées à l'objet (ou faiblement lié) et afin d'éviter que ces opérations contaminent l'objet, vous pouvez utiliser le mode visiteur pour encapsuler ces opérations dans le visiteur.
S'il existe des opérations similaires dans un groupe d'objets, afin d'éviter un grand nombre de code en double, ces opérations en double peuvent également être encapsulées dans le visiteur.
Cependant, le mode visiteur n'est pas si parfait, et il a également des défauts mortels: l'ajout de nouvelles classes d'éléments est plus difficile. Grâce au code du modèle des visiteurs, nous pouvons voir que dans la classe des visiteurs, chaque classe d'élément a sa méthode de traitement correspondante. C'est-à-dire que chaque classe d'éléments doit être ajoutée pour modifier la classe des visiteurs (y compris également la sous-classe ou la classe d'implémentation de la classe Visitor), ce qui est assez gênant à modifier. C'est-à-dire que lorsque le nombre de classes d'éléments est incertain, le mode visiteur doit être utilisé avec prudence. Par conséquent, le mode visiteur est plus adapté pour refactoriser les fonctions existantes. Par exemple, si les fonctions de base d'un projet ont été déterminées, les données des classes d'éléments ont été essentiellement déterminées et ne changent pas. Tout ce qui changera, ce sont les opérations pertinentes au sein de ces éléments. À l'heure actuelle, nous pouvons utiliser le mode visiteur pour refacter le code d'origine, afin que les fonctions d'origine puissent être modifiées sans modifier chaque classe d'élément.
Résumer
En tant que GOF, l'auteur de Design Pattern, décrit le mode visiteur: dans la plupart des cas, vous devez utiliser le mode visiteur, mais une fois que vous en avez besoin, vous en avez vraiment besoin. Bien sûr, ce n'est que pour les vrais gros gars. En réalité (au moins dans l'environnement dans lequel je suis), beaucoup de gens sont souvent accro aux modèles de conception. Lors de l'utilisation d'un modèle de conception, ils ne considèrent jamais sérieusement si le modèle qu'ils utilisent convient à ce scénario, mais veulent souvent montrer leur capacité à contrôler la conception orientée objet. Si vous avez cette mentalité lors de la programmation, vous abusez souvent du modèle de conception. Par conséquent, lors de l'apprentissage des modèles de conception, vous devez comprendre l'applicabilité des modèles. Il est nécessaire d'utiliser un modèle parce que vous comprenez ses avantages, pas pour utiliser un modèle parce que vous comprenez ses inconvénients; Plutôt que d'utiliser un modèle parce que vous ne comprenez pas ses inconvénients, pas pour utiliser un modèle parce que vous ne comprenez pas ses avantages.
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.