Besucher-Muster-Implementierung in java - Wie sieht das aus?
Alrite, ich bin gonna springen Sie direkt zu der code:
public interface Visitor {
public void visitInventory();
public void visitMaxCount();
public void visitCountry();
public void visitSomethingElse();
public void complete();
//the idea of this visitor is that when a validator would visit it, it would validate data
//when a persister visits it, it would persist data, etc, etc.
//not sure if I making sense here...
}
public interface Visitable {
public void accept(Visitor visitor);
}
hier ist eine Basis-Implementierung:
public class StoreValidator implements Visitor {
private List <ValidationError> storeValidationErrors = new ArrayList<ValidationError>();
public void addError(ValidationError error) {
storeValidationErrors.add(error);
}
public List<ValidationError> getErrors() {
return storeValidationErrors;
}
public void visitInventory() {
//do nothing
}
public void visitMaxCount() {
//do nothing
}
//... etc.. all empty implementations
}
Werden Sie sehen, warum ich eine leere Implementierung hier... würde ich schreiben, eine Prüfung jetzt.. das reicht StoreValidator
public XYZValidator extends StoreValidator {
@Override
public void visitInventory(Visitable visitable) {
//do something with visitable .. cast it to expected type
//invoke a DAO, obtain results from DB
//if errors found, do addError(new ValidationError()); with msg.
}
@Override
public void visitMaxCount(Visitable visitable) {
//do something with visitable..
}
//I wouldn't implement the rest coz they wouldn't make sense
//in XYZValidator.. so they are defined as empty in StoreValidator.
}
Nun, hier ist, was ein besuchbar würde wie folgt Aussehen:
public Store implements Visitable {
public void accept(Visitor visitor) {
visitor.visitInventory();
visitor.visitMaxCount();
}
}
Hätte ich code, der etwas tut, wie diese auf eine Liste der Objekte Speichern:
List<Store> stores; //assume this has a list of stores.
StoreValidator validator = new XYZValidator(); //or I would get it from a validatorfactory
for(Store store: stores) {
store.accept(validator); //so even if you send a wrong validator, you are good.
}
Ähnlich wie man es hätte ABCValidator die Implementierung für andere Methoden (visitCountry /visitSomethinElse) und es würde reichen von StoreValidator. Ich hätte eine andere Art von Objekt (nicht Speichern) definieren akzeptieren-Methode.
Sehe ich hier ein problem...
Sagen, ich brauche eine FileValidator anders StoreValidator, würde ich erwarten, dass es keines dieser Unternehmen im Zusammenhang mit Validierungen, wie visitInventory(), etc. Aber, durch eine einzige Schnittstelle-Besucher, ich würde endup deklarieren alle Arten von Methoden in der Visitor-Schnittstelle. Ist das richtig? Ist dies, wie Sie es tun?
Ich weiß nicht, ob ich das Muster habe, falsch ist, oder ob ich mich Sinn macht.
Bitte teilen Sie Ihre Gedanken.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es ein problem mit Ihrem code als gegeben an. Die Schnittstelle, die Sie zu geben hat Methoden wie
aber Sie dann umzusetzen in XYZValidator als
Den Besucher-Muster ist eine Möglichkeit zur Implementierung multiple dispatch in Sprachen, tun Sie das nicht automatisch (wie Java). Eine der Anforderungen ist, dass Sie eine Gruppe von verwandten Klassen (d.h. eine Reihe von Unterklassen, die mit einem einzigen super-Klasse). Sie haben nicht diese hier, so das Besucher-Muster nicht geeignet. Die Aufgabe, die Sie versuchen zu tun,, jedoch, ist in Ordnung, es ist nur nicht das Besucher-Muster.
In Java, sollte man denken, das Besucher-Muster, wenn Sie code wie
besonders, wenn die Unterklassen von Element sind relativ fest.
Vor einiger Zeit schrieb ich etwas ähnliches für meine master-Arbeit. Dieser code ist leicht
Typ sicherer als deins:
Beispiel:
also ja, ich denke, dass dies definitiv eine gute und flexible design, wenn, und nur wenn Sie Ihre Daten ändern sich langsamer als Ihr Verhalten. In meinem Beispiel sind die Daten in Java-bytecode, der behoben wird (definiert durch die JVM-Spezifikation). Wenn "Verhalten beherrscht" (ich will dump, zusammenstellen, umwandeln, umgestalten, usw meine bytecode) das Besucher-Muster lassen Sie zum ändern/hinzufügen/entfernen von Verhaltensweisen ohne Sie zu berühren, Ihre Daten-Klassen. Fügen Sie einfach eine andere Implementierung der Besucher.
Der Einfachheit halber davon ausgehen, dass muss ich hinzufügen weiterer Besuch Methode, um meine Besucher-interface: ich würde am Ende brechen alle meine Codes.
Als alternative würde ich überlegen, die Strategie-Muster für dieses Szenario. Strategie + decorator ist ein gutes design für die Validierung.
Ich bin mit einem Besucher-Muster in einer anderen Art und Weise.. ich habe eine konkrete Visitor-interface für einen Typ von Objekt und das interface deklariert nur eine Methode - für den Besuch dieses Objekt.. so:
Objekt TreeNode akzeptieren kann TreeNodeVisitors, was bedeutet, dass er nur fordert, es ist besuchen - Methode für den Knoten und/oder es sind Kinder..
Die konkrete Implementierung der visitor-implementiert die besuchen Methode und sagt, was die Besucher zu tun.. zum Beispiel ContryVisitor, InventoryVisitor, etc
Dieser Ansatz soll vermeiden, dass Ihre probleam..
Sie wahrscheinlich nicht wollen, ordnen Sie ein Muster direkt zu einem interface, dass alles folgende, das Muster implementiert. Muster sind NICHT Schnittstellen, Sie sind die Allgemeinen Pläne für die Umsetzung einer Lösung.
In deinem Beispiel erstellen Sie eine StoreVisitor-Schnittstelle und ein interface FileVisitor, der für die verschiedenen business-Objekte verwenden möchten, das Besucher-Muster in den entsprechenden Umständen.
Könnte es sein, dass unterschiedliche Visitor-Implementierungen für gemeinsame Aktivitäten - so könnte man ein superinterface definiert, dass diese gemeinsamen Funktionen. Sie könnte dann code Besuchbar-Schnittstellen verwenden entweder die spezifische Besuchbar interface oder Oberklasse als angemessen.
Beispielsweise die FileVisitor und SQLTableVisitor Schnittstellen könnte eine Unterklasse einer DataStoreVisitor-Schnittstelle. Dann:
VisitableStore akzeptiert eine StoreVisitor,
VisitableFile akzeptiert einen Filevisitor, oder
VisitableDataStore akzeptiert eine DataStoreVistor (das könnte auch eine Umsetzung der beiden FileVisitor oder SQLTableVisitor).