Ich benutze das Befehlsmuster schon seit einiger Zeit, bin mir aber nie sicher, wie viel Logik ich tatsächlich in die Execute
Methode einbauen kann .
Meine aktuelle Implementierung des Befehlsmusters sieht folgendermaßen aus:
public abstract class Command
{
public static event EventHandler Completed = delegate { };
public bool Success { get; private set; }
public Exception Exception {get; private set; }
public abstract bool Execute();
protected bool OnCompleted(bool success, Exception ex = null)
{
Success = success;
Exception = ex;
Completed(this, EventArgs.Empty)
return success;
}
}
und das sind die Fragen, die ich mir stelle (und in meinen Befehlen übe):
- Ist es in Ordnung, Nachrichtenfelder anzuzeigen oder Dialoge zum Öffnen von Dateien usw. anzuzeigen?
- Ist es in Ordnung, Eigenschaften eines Objekts festzulegen?
- Kann ein Befehl Geschäftslogik enthalten?
- Kann ein Befehl die GUI-Steuerelemente trotzdem ändern?
- Zu welchen Ebenenbefehlen gehören? Ansicht oder Datenschicht? Kann ich Befehle in beiden Ebenen haben?
- Kann ein Befehl all das tun, was vorher in der war
button1_Click
? - Sollte ein Befehl von Unit-Testable?
- Kann ein Befehl als zu sehen Benutzer , dass Marken die APIs verwenden und baut die letzte Schicht einer Anwendung und auch die letzte Mittel Ausnahmen zu fangen?
- Können Befehle auch per Code ausgeführt werden (Befehl ruft API auf, API wird ausgeführt und schließlich ruft eine andere API einen Befehl auf) oder kann nur der Benutzer ihn aufrufen und die APIs dürfen nichts über ihre Existenz wissen?
- Gibt es einen Platz für Befehle in MVC oder MVVC oder einem anderen Entwurfsmuster mit einer Steuerung? Sie scheinen sich gegenseitig auszuschließen. Was ist vorzuziehen?
Es gibt viele Tutorials, die zeigen, wie das Befehlsmuster implementiert wird, aber keines beschreibt tatsächlich, wie es in einer echten Wold-Anwendung angewendet wird.
Der größte Vorteil von Befehlen besteht darin, dass sie es einfach machen, eine Aktion rückgängig zu machen, eine Aktion zu wiederholen, eine Aktion an mehreren Stellen (über eine Netzwerkverbindung) auszuführen oder sie zu einem späteren Zeitpunkt auszuführen usw.
In diesem Sinne:
Wahrscheinlich nicht. Es ist schwer vorstellbar, dass es sinnvoll ist, ein Dialogfeld "rückgängig zu machen", und so etwas würde ich lieber in den UI-Code einfügen.
Solange auf dieses Objekt von überall aus zugegriffen werden kann, wo der Befehl ausgeführt werden soll, ist es natürlich in Ordnung, seine Eigenschaften zu ändern.
Absolut. Dies hängt davon ab, ob Ihr Modell Geschäftslogik "enthalten" soll. Es wird tatsächlich als Anti-Pattern ("anämisches Domain-Modell") angesehen, um zu wenig Geschäftslogik zu haben.
Wenn die GUI-Steuerelemente Teil Ihres Modells sind, unbedingt. Wenn nicht, ist es fraglich.
Auf keinen Fall die Aussicht. Die Ansicht sollte darüber informiert werden, dass sich die Daten oder das Modell geändert haben, und entsprechend reagieren, aber die tatsächliche Änderung sollte in den Daten oder im Modell stattfinden.
Im Prinzip wahrscheinlich ja. Befehle rückgängig machen zu können, ist eines der besten Dinge an dem Muster.
Die Funktion execute () des Befehls sollte auf jeden Fall einheitlich getestet werden. Wenn Befehle an ein Modell gebunden sind, gehören sie zu den am einfachsten zu testenden Teilen einer Anwendung.
Ich bin mir nicht ganz sicher, was du meinst, aber:
Absolut. Die meisten Vorteile von Befehlen sind unmöglich zu implementieren, wenn der Code sie nie ausführt.
Es ist wahrscheinlich mittlerweile offensichtlich, aber ich sehe sie überhaupt nicht als sich gegenseitig ausschließend an. In meinem Team bei der Arbeit übersetzt der Controller benutzergenerierte Ereignisse in Befehle, das Modell empfängt und führt die Befehle aus (und speichert "Rückgängig" -Befehle irgendwo), und wenn dies erledigt ist, weist der Controller die Ansicht an, sich basierend auf dem neuen Modell selbst zu aktualisieren . Die Befehle werden auch über das Netzwerk an alle Kopien des Modells gesendet, die von anderen Benutzern angezeigt werden, sodass sie es auch sehen. Es funktioniert hervorragend.
Und die Titelfrage: Wie viel Logik muss in einen Befehl eingegeben werden? Ich würde kein Minimum oder Maximum darauf setzen. Was ich sagen würde, ist, dass es eine sehr gute Idee ist, komplexere Befehle mit einer Reihe einfacherer Befehle zu implementieren und Befehle auf die gleiche Weise zu refaktorieren, wie Sie Funktionen refaktorieren würden.
quelle