Definition: Kapuliert bestimmte Operationen, die in einer bestimmten Datenstruktur auf jedes Element wirken. Es kann neue Operationen definieren, die auf diese Elemente reagieren, ohne die Datenstruktur zu ändern.
Typ: Verhaltensmuster
Klassendiagramm:
Beispiel:
Denken Sie beispielsweise über das Hinzufügen verschiedener Warenarten in den Warenkorb und beim Klicken auf die Kasse berechnet die Gebühren, die für alle verschiedenen Waren bezahlt werden sollen. Die Berechnungslogik besteht nun darin, die Preise dieser verschiedenen Arten von Waren zu berechnen. Oder mit anderen Worten, wir übertragen diese Logik in eine andere Klasse über den Besuchermodus. Lassen Sie uns dieses Beispiel des Besuchermusters implementieren.
Um das Besuchermuster zu implementieren, müssen Sie als erstes eine Klasse erstellen, die dem Einkaufswagen hinzugefügt werden kann, um verschiedene Arten von Artikeln (Elementelemente) darzustellen.
Itemelement.javapackage com.journaldev.design.visor; öffentliche Schnittstelle Elementelement {public int Accept (ShoppingCartvisitor -Besucher);}Beachten Sie, dass die Akzeptanzmethode den Besucher als Parameter akzeptiert. Natürlich gibt es hier noch andere Möglichkeiten, um detaillierte Produkte anzugeben, aber der Einfachheit halber muss hier nicht zu viele Details berücksichtigt werden und sich nur auf den Besuchermodus konzentrieren.
Erstellen Sie nun einige Entitätsklassen für verschiedene Produkte.
Book.java
Paket com.journaldev.design.visor; Public Class Book implementiert Elementelement {private int preis; private String isbnnumber; public book (int cost, string isbn) {this.price = cost; this.isbnnumber = isbn; } public int getPrice () {Rückgabepreis; } public String getisbnNumber () {return isbnnumber; } @Override public int Accept (ShoppingCartvisitor Visitor) {return Visitor.vissit (this); }}Fruit.java
Paket com.journaldev.design.visor; öffentliche Klasse Obst implementiert Elementelement {private int priceperkg; Privat int Gewicht; privater Zeichenfolge Name; öffentliche Frucht (int pricekg, int wt, String nm) {this.PricePerkg = Pricekg; this.gewicht = wt; this.name = nm; } public int getPricePerkg () {Return PriceperKg; } public int get wweight () {return Gewicht; } public String getName () {return this.name; } @Override public int Accept (ShoppingCartvisitor Visitor) {return Visitor.vissit (this); }} Beachten Sie, dass die Implementierung der Accept () -Methode in der Entitätsklasse liegt, die die Methode des Besuchs besuchte (), um das aktuelle Klassenobjekt als seinen eigenen Parameter zu übergeben.
Hier wird die für verschiedene Arten von Waren verwendete Visit () -Methode in der Entitätsklasse der Besucherschnittstelle implementiert.
ShoppingCartvisitor.java
Paket com.journaldev.design.visor; public interface ShoppingCartvisitor {int Visit (Buchbuch); int Besuch (Fruchtfrucht);}Die Besucherschnittstelle wird nun implementiert und die Logik der Berechnung ihrer eigenen Ausgaben für jedes Produkt.
ShoppingCartvisitorImpl.java
paket com.journaldev.design.visor; public class coppingCartvisitorImpl implements coppingCartvisitor {@Override public int besuchen (buchbuch) {int cost = 0; // 5 $ Rabatt anwenden, wenn der Buchpreis größer als 50 ist, wenn (book.getPrice ()> 50) {cost = book.getPrice ()-5; } else cost = book.getPrice (); System.out.println ("Buch isbn ::"+book.getIsbnnumber ()+"cost ="+cost); Rückgabekosten; } @Override public int Visit (Fruchtfrucht) {int cost = fruit.getPricePerkg ()*fruit.getWeight (); System.out.println (fruit.getName () + "cost =" + cost); Rückgabekosten; }}Lassen Sie uns nun sehen, wie man es im Programm verwendet.
ShoppingCartClient.java
Paket com.journaldev.design.visor; public class coppingCartclient {public static void main (String [] args) {itemElement [] items = new itemelement [] {New Book (20, "1234"), neues Buch (100, "5678"), New Fruit (10, 2, 2, Banana), New Fruit (5, 5, 5, 5, "). int Total = CalculatePrice (Elemente); System.out.println ("Total Cost ="+Total); } private static int calculatePrice (itemElement [] Artikel) {ShoppingCartvisitor Visitor = new ShoppingCartvisitorImpl (); int sum = 0; für (Elementelement Element: Elemente) {sum = sum + item.accept (Besucher); } Return Sum; }}Beim Ausführen des obigen Programms erhalten wir die folgende Ausgabe.
Buch ISBN :: 1234 Kosten = 20Book ISBN :: 5678 Kosten = 95Banana Kosten = 20apple Kosten = 25 Totalkosten = 160
Bitte beachten Sie, dass die Implementierung hier für alle Produkte die gleiche wie die Accept () -Methode zu sein scheint, aber auch unterschiedlich sein kann. Wenn das Produkt beispielsweise leer ist, kann es logische Überprüfungen durchführen und die Methode besuch () nicht mehr aufgerufen.
Vorteile des Besuchermodus:
Entsprechen Sie dem Prinzip der einzigen Verantwortung: In jedem Szenario, in dem der Besuchermodus anwendbar ist, müssen die Operationen, die im Besucher in der Elementklasse eingekapselt werden müssen, Operationen sein, die wenig mit der Elementklasse selbst zu tun haben und volatil sind. Einerseits entspricht die Verwendung des Besuchermodus dem Prinzip der einzelnen Verantwortung und andererseits, da die eingekapselten Operationen normalerweise volatil sind. Wenn Änderungen auftreten, kann die Erweiterung des sich ändernden Teils erreicht werden, ohne die Elementklasse selbst zu ändern.
Gute Skalierbarkeit: Elementklassen können unterschiedliche Vorgänge erweitern, indem sie verschiedene Besucher akzeptieren.
Anwendbare Szenarien für den Besuchermodus:
Wenn in einem Objekt einige Operationen vorhanden sind, die nicht mit dem Objekt (oder schwach verwandt) zusammenhängen, und um zu vermeiden, dass diese Operationen das Objekt kontaminieren, können Sie den Besuchermodus verwenden, um diese Operationen in den Besucher einzudämmen.
Wenn in einer Gruppe von Objekten ähnliche Operationen vorhanden sind, können diese doppelten Vorgänge auch in den Besucher eingekapselt werden, um eine große Anzahl doppelter Code zu vermeiden.
Der Besuchermodus ist jedoch nicht so perfekt und hat auch fatale Fehler: Das Hinzufügen neuer Elementklassen ist schwieriger. Durch den Code des Besuchermusters können wir sehen, dass in der Besucherklasse jede Elementklasse ihre entsprechende Verarbeitungsmethode hat. Das heißt, jede Elementklasse muss hinzugefügt werden, um die Besucherklasse (auch die Unterklasse oder die Implementierungsklasse der Besucherklasse) zu ändern, was zu ändern ist. Das heißt, wenn die Anzahl der Elementklassen ungewiss ist, sollte der Besuchermodus mit Vorsicht verwendet werden. Daher eignet sich der Besuchermodus besser zum Wiederaufbau bestehender Funktionen. Wenn beispielsweise die grundlegenden Funktionen eines Projekts bestimmt wurden, wurden die Daten von Elementklassen im Grunde ermittelt und ändert sich nicht. Alles, was sich ändern wird, sind die relevanten Operationen innerhalb dieser Elemente. Zu diesem Zeitpunkt können wir den Besuchermodus verwenden, um den ursprünglichen Code neu zu gestalten, damit die ursprünglichen Funktionen geändert werden können, ohne jede Elementklasse zu ändern.
Zusammenfassen:
Als GOF beschreibt der Autor von Designmuster den Besuchermodus: In den meisten Fällen müssen Sie den Besuchermodus verwenden, aber sobald Sie ihn benötigen, benötigen Sie es wirklich. Natürlich ist das nur für die wirklich großen Jungs. In der Realität (zumindest in der Umgebung, in der ich mich befinde) sind viele Menschen oft von Designmustern abhängig. Bei Verwendung eines Entwurfsmusters überlegen sie nie ernsthaft, ob das von ihnen verwendete Muster für dieses Szenario geeignet ist, möchten aber oft nur ihre Fähigkeit zeigen, objektorientiertes Design zu steuern. Wenn Sie diese Mentalität beim Programmieren haben, missbrauchen Sie häufig das Designmuster. Daher müssen Sie beim Lernen von Entwurfsmustern die Anwendbarkeit der Muster verstehen. Es ist notwendig, ein Muster zu verwenden, da Sie seine Vorteile verstehen und kein Muster verwenden, da Sie seine Nachteile verstehen. Anstatt ein Muster zu verwenden, weil Sie seine Nachteile nicht verstehen, um kein Muster zu verwenden, da Sie seine Vorteile nicht verstehen.