Witzig, diese Frage erinnerte mich nur an genau dasselbe Gespräch, das ich mit einem unserer Ingenieure über die Kommunikationsbibliothek geführt hatte, an der ich arbeitete.
Anstelle von Befehlen hatte ich Request-Klassen und dann RequestHandler. Das Design war sehr ähnlich zu dem, was Sie beschreiben. Ich denke, ein Teil der Verwirrung, die Sie haben, ist, dass Sie das englische Wort "command" sehen und sofort "verb, action ... etc" denken.
Stellen Sie sich Command (oder Request) in diesem Entwurf jedoch als Buchstaben vor. Oder für diejenigen, die nicht wissen, was ein Postdienst ist, denken Sie an E-Mail. Es ist einfach Inhalt, entkoppelt davon, wie auf diesen Inhalt reagiert werden soll.
Wieso würdest du das machen? In den meisten einfachen Fällen gibt es für Command Pattern keinen Grund, und Sie könnten diese Klasse direkt arbeiten lassen. Die Entkopplung wie in Ihrem Entwurf ist jedoch sinnvoll, wenn Ihre Aktion / Ihr Befehl / Ihre Anforderung eine gewisse Strecke zurücklegen muss. Zum Beispiel über Sockets oder Pipes oder zwischen Domäne und Infrastruktur. Oder vielleicht müssen Ihre Befehle in Ihrer Architektur persistent sein (z. B. kann der Befehlshandler aufgrund einiger Systemereignisse jeweils 1 Befehl ausführen, 200 Befehle treffen ein und nach dem Herunterfahren der ersten 40 Prozesse). In diesem Fall ist es mit einer einfachen Nur-Nachrichten-Klasse sehr einfach, nur den Nachrichtenteil in JSON / XML / binary / whatever zu serialisieren und über die Pipeline weiterzuleiten, bis der Befehlshandler bereit ist, ihn zu verarbeiten.
Ein weiterer Vorteil der Entkopplung von Command von CommandHandler besteht darin, dass Sie jetzt die Möglichkeit haben, eine parallele Vererbungshierarchie zu erstellen. Beispielsweise könnten alle Ihre Befehle von einer Basisbefehlsklasse abgeleitet werden, die die Serialisierung unterstützt. Und vielleicht haben Sie 4 von 20 Befehlshandlern, die eine große Ähnlichkeit aufweisen, jetzt können Sie die von der Came-Handler-Basisklasse ableiten. Wenn Sie Daten- und Befehlsverarbeitung in einer Klasse haben würden, würde diese Art von Beziehung schnell außer Kontrolle geraten.
Ein weiteres Beispiel für die Entkopplung wäre, wenn Ihr Befehl nur sehr wenige Eingaben erfordert (z. B. 2 Ganzzahlen und eine Zeichenfolge), die Verarbeitungslogik jedoch so komplex ist, dass Sie Daten in den Variablen der Zwischenelemente speichern möchten. Wenn Sie 50 Befehle in die Warteschlange stellen, möchten Sie nicht den gesamten Zwischenspeicher belegen. Trennen Sie daher Command von CommandHandler. Jetzt stellen Sie 50 leichte Datenstrukturen in die Warteschlange, und komplexerer Datenspeicher wird vom CommandHandler, der die Befehle verarbeitet, nur einmal (oder N-mal, wenn Sie N-Handler haben) zugewiesen.