Wie kann ich die Benutzeroberfläche von der Geschäftslogik trennen, ohne die Effizienz zu beeinträchtigen?

19

Angenommen, ich möchte ein Formular anzeigen, das 10 verschiedene Objekte in einer Combobox darstellt. Zum Beispiel möchte ich, dass der Benutzer einen Hamburger aus 10 verschiedenen mit Tomaten auswählt.

Da ich UI und Logik trennen möchte, müsste ich das Formular als Zeichenfolgendarstellung der Hamburger übergeben, um sie in der Combobox anzuzeigen. Andernfalls müsste die Benutzeroberfläche in die Objektfelder greifen. Dann würde der Benutzer einen Hamburger aus der Combobox auswählen und ihn an den Controller zurücksenden. Jetzt müsste der Controller den Hamburger anhand der vom Formular verwendeten String-Darstellung (evtl. eine ID?) Wiederfinden.

Ist das nicht unglaublich ineffizient? Sie hatten bereits die Objekte, aus denen Sie eines auswählen wollten. Wenn Sie das gesamte Objekt an das Formular gesendet und dann ein bestimmtes Objekt zurückgegeben haben, müssen Sie es später nicht erneut suchen, da das Formular bereits einen Verweis auf dieses Objekt zurückgegeben hat.

Außerdem, wenn ich falsch liege und Sie das gesamte Objekt tatsächlich an das Formular senden sollten, wie kann ich die Benutzeroberfläche von der Logik isolieren?

Uri
quelle
Inwiefern wäre es ineffizient? In jedem Fall müssen Sie dem Benutzer eine Zeichenfolgendarstellung anzeigen und seine Antwort dem ursprünglichen Objekt zuordnen.
Simon Bergot
Das Problem ist, dass ich es erneut holen muss, nachdem der Benutzer es ausgewählt hat, um mit dem Objekt zu arbeiten.
Uri

Antworten:

34

Zuallererst ist das von Ihnen bereitgestellte Beispiel nicht unglaublich ineffizient. es ist nur wenig ineffizient; seine ineffizienz liegt unter dem wahrnehmbaren niveau. Aber fahren wir auf jeden Fall mit der Frage fort.

So wie ich es verstehe, meinen wir , wenn wir von der Trennung von UI und Logik sprechen , die Vermeidung von enger Kopplung .

Eine enge Kopplung bezieht sich auf die Situation, in der die Benutzeroberfläche die Logik kennt (und aufruft) und die Logik die Benutzeroberfläche kennt (und aufruft). Um eine enge Kopplung zu vermeiden, muss nicht auf die vollständige Aufhebung der Kopplung zurückgegriffen werden. (Das scheint Ihr Ziel zu sein, indem Sie die Schnittstelle zwischen ihnen bis zu einer Zeichenfolgenschnittstelle mit dem geringsten gemeinsamen Nenner zerstören.) Alles, was Sie tun müssen, ist, eine lose Kopplung zu verwenden .

Lose Kopplung bedeutet, dass A B kennt, B jedoch nicht A. Mit anderen Worten, die beiden beteiligten Parteien spielen unterschiedliche Client- und Serverrollen , wobei der Client den Server kennt, der Server den Client jedoch nicht.

Im Fall von Benutzeroberfläche und Logik ist meiner Meinung nach die beste Möglichkeit, dies zu arrangieren, die Logik als Server und die Benutzeroberfläche als Client zu betrachten. Die Benutzeroberfläche ist also für die Logik konzipiert, kennt die Logik und ruft die Logik auf, während die Logik nichts über die Benutzeroberfläche weiß und einfach auf die empfangenen Anforderungen antwortet. (Und diese Anfragen kommen zufällig von der Benutzeroberfläche, aber die Logik weiß das nicht.)

Praktischer ausgedrückt, sollten Sie nirgendwo in den Quellcodedateien der Logik Include- / Import- / Using-Anweisungen finden, die sich auf UI-Dateien beziehen, während die Quellcodedateien der UI voll von Include- / Import- / Using-Anweisungen sind Anweisungen, die sich auf Logikdateien beziehen.

Um auf Ihren Fall zurückzukommen, es ist absolut nichts falsch daran, dass der UI-Code, der das Kombinationsfeld ausfüllt, über die Hamburger-Klasse Bescheid weiß. Es würde ein Problem geben, wenn die Hamburger-Klasse etwas über Combo-Boxen wüsste.

Übrigens erlaubt dieses Design eine andere Sache, die Sie von einem solchen System erwarten sollten: Es sollte möglich sein, beliebig viele verschiedene Benutzeroberflächen an die Logik anzuschließen, und das Ganze sollte immer noch funktionieren.

Mike Nakis
quelle
5

Sie sollten jedes Teil des Modells, der Ansicht und des Controllers trennen , aber es gibt keinen Grund, warum Sie (zum Beispiel) keine Modellobjekte zwischen dem Controller und der Ansicht übertragen können.

Also in Ihrem Fall, die Hamburgerwürden Objekte Teil des Modells sein. Anschließend rufen Sie mit Ihrem Controller die erforderliche Liste von Hamburgers ab und übergeben diese Objekte zur Anzeige an die Ansicht (das Kombinationsfeld). Wenn Ihr Benutzer den gewünschten Hamburger ausgewählt hat, können Sie das HamburgerObjekt zur weiteren Verarbeitung an den Controller zurückgeben.

Der Punkt ist, dass Sie die "Fetch Hamburgers" -Logik und die "Process Hamburger" -Logik immer noch separat von der tatsächlichen Anzeige der Hamburger testen können .

Dean Harding
quelle
Ich verstehe. Wenn ich jedoch die Hamburguer-Klasse ändere, muss ich dann nicht auch den Code des Formulars ändern, der sich mit den Hamburguer-Objekten befasst? Wo ist dann die UI-Logic Trennung?
Uri
2
Der Hamburger ist Teil des Modells. Wenn Sie das Modell ändern, ändern Sie am Ende die Ansicht und den Controller. Das Modell ist die Trennung zwischen Benutzeroberfläche und Logik. Das Berühren ist mit höheren Kosten verbunden, daher sollten Sie beim Entwerfen vorsichtig sein.
Simon Bergot