Hi!
Versteht jemand, was ich meine? Irgendwie habe ich ein Problem, Model, View und Controller konkret auseinanderzuhalten bzw. überhaupt zu bauen. Hat mein Konzept deshalb einen Designfehler? Hat es überhaupt etwas mit dem MVC-Muster zu tun oder kann man MVC für mein Beispiel gar nicht brauchen?
Du beschreibst mehr oder weniger eine ziemlich komplexe Geschäftslogik. Die kannst du nicht komplett in eine einzelne Instanz eines Model-View-Controller-Trios packen. MVC ist ein Muster, wie eine Benutzeraktion/-eingabe durch den Controller gesteuert in Richtung Model eine Aktion mit Daten (speichern, lesen, irgendwohin senden, etwas berechnen) ausführt und das Ergebnis in eine View bringt, die etwas für den Anwender Sichtbares erzeugt.
Die Kellnerin wäre vielleicht eine Art Controller. Sie nimmt die Eingabe entgegen, reicht sie an das Model weiter, was in einem Fall die Küche ist, im anderen die Theke und zum Schluss die Kasse. Views wären dann die Auslieferung des Bestellten und der Rechnung. Dass die Kellnerin bei einer Anforderung erst zu einem Tisch hinlaufen muss, könnte man vernachlässigen. Theoretisch könnten die Gäste ihre Bestellungen auch quer durch den Raum rufen. Allerdings kann man das auch in eine MVC-Aktion bringen: Gast macht sich bemerkbar, Model braucht es dafür keins, die View ist die Präsenz der Kellnerin mit dem Eingabeformular für den Gast - sprich: ihren gespitzen Ohren.
Nun ist es ja so, dass die Aktionen teilweise recht lange dauern. Während des MVC-Zyklus für die Bestellung eines Essens und dessen Auslieferung werden weitere Ereignisse ausgelöst, weil andere Gäste auch Wünsche haben. Schon wenn einer zwei Wünsche hat - Essen und Getränk sind bereits zwei - kann das ein Controller erledigen. Dazu würde ich für jeden Request einen neuen Thread eröffnen. Deine Kellnerin muss für eine ordnungsgemäße Ausführung allerdings thread-safe sein. Die Request-Threads werden jeweils für sich zum jeweiligen Model (Küche, Bar, etc.) geleitet und auf dessen Fertigstellung gewartet, bevor die Ausliefung als View erfolgen kann.
Die Ereignisauslösung ist aber nicht Teil des MVC-Musters. Für die Simulierung der Gäste und der Generierung ihrer Wünsche musst du dir was anderes ausdenken. - Im wahren Leben muss die Kellnerin auch darauf achten, dass die Gäste nicht ohne zu Bezahlen verschwinden. Hierzu könntest du ein Observer-Pattern einbauen. Des ist ebenfalls kein Bestandteil des MVC-Musters. Das Observieren würde ich in einem Programm einer anderen Instanz als der Kellnerin überhelfen. Wenn jedoch der Observer anschlägt, muss das zu einem Request an den Controller führen, der eine View an den Platz schickt, die an die noch notwendige Rechnungswunsch-Aktion erinnert.
Im wirklichen Restaurant-Betrieb ist das Observer-Pattern noch deutlich häufiger in Verwendung. Die Kellnerin eröffnet in ihrem Gedächtnis nicht unbedingt für jeden Bestellungsteil einen Thread. Vielmehr bündelt sie erstmal alles, sortiert es dann für Küche und Bar auseinander und unterbricht diesen Request erst einmal. Mit dem Observer-Pattern in Richtung Küche und Bar wird sie beim Fertigstellen informiert und nimmt dann ihre Arbeit wieder auf. Für eine solche Simulation ist das MVC-Pattern vielleicht nicht mehr das Richtige, weil der typische MVC-Zyklus unterbrochen wird. Aber viele Wege führen nach Rom und man kann durchaus auch das MVC-Pattern nehmen und es nach Belieben umgestalten.
Wie du vielleicht feststellen wirst, bin ich nicht auf alle Einzelheiten deiner Beschreibung eingegangen, denn beispielsweise gleich die ersten
– Beliebig viele Tische mit je sechs Sitzplätzen
– Eine Karte mit Speisen und Getränken
sind für das MVC-Pattern nicht von Belang. Auch hast du eher ein Thema gewählt, das mit einer Echtzeit-Simulation besser realisiert werden kann als mit einer Webanwendung, die ja immer nur jeweils einen Request abarbeitet und dazwischen nichts macht. Du müsstest deine Gäste außerhalb der Anwendung platzieren, denn ansonsten hast du keine Ereignisse, auf die dein Controller reagieren könnte. Das hat auch noch weitere Nachteile, weil die Gäste pro Request ein neues Browser-Fenster öffnen müssen oder zumindest je einen Ajax-Request, denn eine asynchrone Rückmeldung seitens des Servers ist nicht vorgesehen. (Bitte nicht verwechseln mit dem asynchronen Einbau der Response in die Webseite.) Entweder der Gast bekommt sein Essen/Getränk mit der Response zum Request oder er pollt ständig, ob das Zeug fertig ist. Das entspricht jedoch eher einem McDonalds-Restaurant, bei dem vieles schon ferig ist, maches aber noch eine Weile braucht und dessen Fertigstellung an einer Schautafel angekündigt wird. Außerdem müsste irgendwas im Hintergrund zum einen solche Requests abarbeiten und andererseits auf Vorrat Produkte ("Speisen" will ich es lieber nicht nennen) erzeugen, was auch nicht in den üblichen Ausführungen von Webservern implementiert ist.
Lo!