Das Besucherdesignmuster ist eine Möglichkeit, einen Algorithmus von einer Objektstruktur zu trennen, auf der er arbeitet. Das ist offizielle Definition davon. Ich versuche herauszufinden, wie dies die Kapselung nicht unterbricht. Wenn ich zum Beispiel unterschiedliche Arten von Klassen für verschiedene Arten von Bankkonten [Speichern / Fixed / Current] zur Implementierung eines abstrakten Klassenkontos verwende, sollte ich die Berechnungszinsmethode als abstrakte Methode in die abstrakte Kontoklasse setzen oder kann ich das Konto senden Geben Sie die Visitor-Implementierung ein und berechnen Sie sie dort?
Methode 1: Soll die Besucher-Implementierung für die Berechnung der Zinsen für die verschiedenen Kontotypen zuständig sein?
%Vor%Methode 2: Oder sollten die Implementierer der Klasse "Account" dies tun?
%Vor%Wenn ich Methode 1 verwende, bei der es sich um die Besucherimplementierung handelt, die den IInterestVisitor wie oben implementiert, wird die Aufgabe, Zinsen zu berechnen, an die Besucherklasse delegiert. Wenn ich bei diesem Ansatz einen anderen Kontotyp hinzufüge, muss ich die Besucherimplementierung jedes Mal ändern, wenn ein neues Konto hinzukommt.
Wenn ich jedoch das Zinsberechnungsbit den abstrakten Account-Klassen-Implementierungen wie oben in Methode 2 überlasse, dann korrigiere ich meiner Meinung nach [ mich, wenn ich hier falsch liege ]. Darüber hinaus gibt es weniger Code zum Ändern, da ich nur eine neue Klasse hinzufüge und den Besucher dazu bringen möchte, eine Schnittstelle wie die folgende zu implementieren:
%Vor%Wie Sie sehen, ist für die Klasse interest visitor, die Methode 2 verwendet, keine Änderung erforderlich. Wird die Kapselung durch Methode 1 unterbrochen? Kann Methode 2 noch als Besuchermuster bezeichnet werden?
Danke fürs Lesen ...
MitVisitor können Sie eine neue Operation definieren, ohne die Klassen zu ändern der Elemente, auf denen es funktioniert.
In dem bereitgestellten Code sehe ich nicht, dass Sie ein Objekt ändern müssen, um Ihren Anforderungen zu entsprechen. Was Visitor
im Grunde tut, ist der Status des Objekts, indem Sie Properties
/ Methods
/ Fields
verwenden. des Objekts selbst.
Also, bei mir passt dein Code in das Besuchermuster, wenn das tatsächlich eine Frage war, verursachen auch Muster Richtlinien und nicht starre Regeln.
Ich persönlich würde den zweiten Weg wählen, da es viel klarer und OOP-orientiert ist.
Grüße.
Ich sehe hier überhaupt keinen Besucher - Ihr Ansatz zeigt perfekt, dass Sie dieses Problem nur mit Polymorphismus lösen können, indem Sie eine CalculateInterestAmount
-Methode verwenden, die die Unterklassen implementieren können.
Meiner Meinung nach brauchen Sie wirklich einen sehr zwingenden Fall, um das Besuchermuster in Betracht zu ziehen - die meisten anderen Lösungen sind einfacher und passen natürlicher.
Nachdem Sie das gesagt haben, verwendet Ihre Version 2 wirklich nur Polymorphie - es gibt keinen Vorteil, einen Besucher auf diese Weise zu verwenden. Version 1 illustriert den "double dispatch" -Ansatz eines Besuchers besser, so arbeitet ein Besucher in der Regel.
Hier ist ein Beispiel für einen Besucher, der den Status auf viele Arten anzeigt, ohne die ursprünglichen Account-Klassen / -Objekte zu beeinflussen. Es ist nicht gut, Fähigkeiten von Besuchern in virtuellen Funktionen wie PrintReport (), SmsReport () usw. zu ersetzen, wo Sie zu viele Methoden haben, um zu implementieren. Mit Visitor können Sie die Funktionen auf andere Weise erweitern, ohne das Objekt zu beeinflussen. Ich habe dieses Beispiel gegeben, da Sie gefragt haben, wo ein Besucher passt . Meiner Meinung nach würde der Besucher nicht zu den beiden Methoden passen, die Sie erwähnt haben.
%Vor%Sehen Sie, ob Sie eine Anwendung haben, wie Sie Visitor verwenden können.
%Vor%Der Besucher hilft in Situationen, in denen die Logik sowohl vom Typ des Gesehenen als auch vom Typ des Besuchers abhängen kann - es ist eine Möglichkeit, den doppelten Versand zu strukturieren.
In Ihrem Szenario haben Sie eine Anforderung, Zinsen zu berechnen, und dies ist eine vernünftige Operation eines Kontos und hängt sehr klar von der Art des Kontos ab. Daher, wie Sie darauf hinweisen, fügt der Besucher keinen Wert hinzu und scheint unpassend zu sein.
Nehmen wir nun einen etwas komplexeren Satz von Berechnungen. Stellen Sie sich vor, Sie haben eine Vielzahl von Sparkonten, einige sind regelmäßige Sparkonten, einige sind an das Börsenverhalten gebunden, einige haben Lebensversicherungsbestandteile. Für solche Konten haben wir Methoden, um Daten wie Zinssätze, Bonussätze, regelmäßige Zahlungspläne, Fälligkeitstermine usw. zu erhalten, die jeweils für verschiedene Arten von Konten unterschiedlich sind.
Wir müssen auch bestimmte Berechnungen durchführen: Was ist der prognostizierte Wert des Accounts an einem bestimmten Datum? Wie hoch ist der Wert des Kontos als Kreditvereinbarung? Welchen Wert hat das Konto, wenn es heute geschlossen wird? Solche Berechnungen müssen für jeden Kontotyp anders ausgeführt werden (vielleicht mit den Rohdaten-Gettern).
Jetzt sehen wir einen Wert in einem Besuchermuster. Als wir eine neue interessante Berechnung entwickeln, schreiben wir einen neuen Besucher, wir müssen keine neuen Versionen der Kontoklassen veröffentlichen.
@Tigran hat darauf hingewiesen, dass Besucher nützlich ist, wenn Sie die besuchten Klassen nicht ändern können.
Da Sie C # verwenden, ist es wahrscheinlich modularer und effektiver, Erweiterungsmethoden zu verwenden >. Sie machen dasselbe, indem sie einem Typ nachträglich Funktionalität hinzufügen, aber Sie müssen nicht mehr alle möglichen Implementierungen an einem Ort herumtragen.
Tags und Links c# design-patterns