Jak oddzielić interfejs użytkownika od logiki biznesowej, zachowując jednocześnie wydajność?

19

Powiedzmy, że chcę pokazać formularz, który reprezentuje 10 różnych obiektów na comboboxie. Na przykład chcę, aby użytkownik wybrał jednego hamburgera spośród 10 różnych zawierających pomidory.

Ponieważ chcę oddzielić interfejs użytkownika od logiki, musiałbym przekazać formularz reprezentujący ciąg hamburgerów w celu wyświetlenia ich na comboboxie. W przeciwnym razie interfejs użytkownika musiałby wkopać się w pola obiektów. Następnie użytkownik wybiera hamburguera z opakowania zbiorczego i przesyła go z powrotem do kontrolera. Teraz kontroler musiałby ponownie znaleźć wspomnianego hamburguera na podstawie reprezentacji łańcucha używanej przez formularz (może identyfikator?).

Czy to nie jest niewiarygodnie nieefektywne? Masz już przedmioty, z których chciałeś wybrać jeden. Jeśli przesłałeś do formularza całe obiekty, a następnie zwróciłeś określony obiekt, nie będziesz musiał go później odnawiać, ponieważ formularz już zwrócił odwołanie do tego obiektu.

Co więcej, jeśli się mylę i rzeczywiście powinieneś wysłać cały obiekt do formularza, jak mogę odizolować interfejs od logiki?

Uri
źródło
W jaki sposób byłoby to nieefektywne? W każdym przypadku musisz pokazać użytkownikowi ciąg znaków i odwzorować jego odpowiedź na oryginalny obiekt.
Simon Bergot
Problem polega na tym, że aby pracować z tym obiektem, muszę go pobrać ponownie po wybraniu go przez użytkownika.
Uri

Odpowiedzi:

34

Po pierwsze, podany przez ciebie przykład nie jest niewiarygodnie nieefektywny; jest tylko nieznacznie nieefektywny; jego nieefektywność jest poniżej wyczuwalnego poziomu. Ale w każdym razie przejdźmy do pytania.

W moim rozumieniu, kiedy mówimy o oddzieleniu interfejsu użytkownika od logiki , mamy na myśli unikanie ścisłego sprzężenia .

Bliskie sprzężenie odnosi się do sytuacji, w której interfejs użytkownika zna (i wywołuje) logikę, a logika zna (i wywołuje) interfejs użytkownika. Aby uniknąć ścisłego połączenia, nie trzeba całkowicie rezygnować z połączenia. (Wydaje się, że celem tego jest wyburzenie interfejsu między nimi do interfejsu łańcucha znaków o najmniejszym wspólnym mianowniku.) Wystarczy zastosować luźne sprzęganie .

Luźne sprzężenie oznacza, że ​​A zna B, ale B nie zna A. Innymi słowy, obie zaangażowane strony odgrywają różne role klienta i serwera , gdzie klient zna serwer, ale serwer nie zna klienta.

W przypadku interfejsu użytkownika i logiki najlepszym sposobem na zaaranżowanie tego jest moim zdaniem logika jako serwer, a interfejs użytkownika jako klient. Tak więc interfejs użytkownika jest zbudowany dla logiki, ma wiedzę na temat logiki i wywołuje logikę, podczas gdy logika nie wie nic o interfejsie użytkownika i po prostu odpowiada na otrzymane żądania. (I te żądania zdarzają się z interfejsu użytkownika, ale logika tego nie wie).

Mówiąc prościej, nigdzie w plikach kodu źródłowego logiki nie powinny znajdować się instrukcje dołączania / importu / używania, które odnoszą się do plików interfejsu użytkownika, podczas gdy pliki kodu źródłowego interfejsu użytkownika będą pełne dołączania / importu / używania instrukcje odnoszące się do plików logicznych.

Tak więc, aby wrócić do twojej sprawy, nie ma absolutnie nic złego w tym, że kod interfejsu użytkownika wypełniający pole kombi wie o klasie hamburgerów. Byłoby problem, gdyby klasa hamburgerów wiedziała coś o pudełkach kombinowanych.

Nawiasem mówiąc, ta konstrukcja pozwala na kolejną rzecz, której powinieneś oczekiwać od takiego systemu: powinna być możliwość podłączenia dowolnej liczby interfejsów użytkownika do logiki, a całość powinna nadal działać.

Mike Nakis
źródło
5

Należy oddzielić każdy element modelu, widoku i kontrolera, ale nie ma powodu, dla którego nie można (na przykład) przekazywać obiektów modelu między kontrolerem a widokiem.

W twoim przypadku Hamburgerobiekty byłyby częścią Modelu. Następnie użyj kontrolera, aby pobrać wymaganą listę Hamburgers i przekazać te obiekty do widoku (combobox) w celu wyświetlenia. Gdy użytkownik wybierze hamburgera, możesz ponownie przekazać Hamburgerobiekt do kontrolera w celu przetworzenia.

Chodzi o to, że nadal możesz testować jednostkowo Hamburgerlogikę „fetch s” i logikę „proces Hamburger” oddzielnie od rzeczywistego wyświetlania hamburgerów.

Dean Harding
źródło
Rozumiem. Jednak jeśli zmodyfikuję klasę Hamburguer, czy nie będę musiał również modyfikować kodu formularza, który dotyczy obiektów Hamburguer? Gdzie zatem jest separacja UI-Logic?
Uri
2
Hamburger jest częścią modelu. Kiedy modyfikujesz model, modyfikujesz widok i kontroler. Model jest oddzieleniem interfejsu użytkownika od logiki. Dotykanie go ma wyższy koszt, dlatego należy zachować ostrożność podczas jego projektowania.
Simon Bergot