2011-02-01 12 views
24

Wiem, że używanie modeli domen jako modeli widoku może być złe. Jeśli mój model domeny ma właściwość o nazwie IsAdmin i mam akcję Create controller, aby tworzyć użytkowników, ktoś mógłby zmienić mój formularz i przekazać go POST IsAdmin = true value formularza, nawet jeśli nie wyeksponowałem takiego pola tekstowego w moim widoku . Jeśli używam wiązania modelu, to po zatwierdzeniu mojego modelu domeny ta osoba będzie teraz administratorem. Tak więc rozwiązanie ujawnia tylko te właściwości, których potrzebuję w modelu widoku i za pomocą narzędzia takiego jak AutoMapper, aby odwzorować wartości właściwości mojego zwracanego obiektu modelu widoku na obiekt mojego modelu domeny. Ale przeczytałem, że atrybut wiązania na klasie może być używany do instruowania modułu wiążącego, które właściwości powinien i nie powinien wiązać. Więc co tak naprawdę jest przyczyną tworzenia dwóch oddzielnych klas (modelu domeny i modelu widoku), które są istotne, reprezentują to samo, a następnie generują narzut w ich mapowaniu? Czy jest to raczej kwestia organizacji kodu, a jeśli tak, to w jaki sposób uzyskuję korzyści?Dlaczego dwie klasy, model widoku i model domeny?

EDIT

Jednym z najważniejszych powodów, natrafiłem na widoku modelu, który jest oddzielony od Domain modelu jest potrzeba wdrożenia wzorca MVVM (w oparciu o Martina Fowlera PM wzór) do zarządzania złożone interfejsy użytkownika.

+1

Sprawdź również to pytanie http://stackoverflow.com/questions/3094633/bestpractice-mixing-view-model-with-domain-model –

Odpowiedz

18

Zauważyłem, że podczas gdy mój model domeny daje mi 85% drogi do posiadania pól, które chcę, nigdy nie pokrył 100% wartości, które chcę na moim widoku. Zwłaszcza jeśli chodzi o uprawnienia i czy użytkownik powinien mieć dostęp do niektórych części widoku.

Koncepcja projektu, którą staram się naśladować, to mieć jak najmniej logiki w moich poglądach. Oznacza to, że mam pola w moim modelu widoku, takie jak "CanViewThisField" lub "CanEditThisField". Kiedy zaczynałem od MVC, mój model domeny byłby moim modelem widokowym i zawsze wpadałem na scenariusz, w którym potrzebowałem tylko jednego lub dwóch dodatkowych pól, aby mój widok był mniej zagracony. Odtąd udałem się na trasę View Model/Model Builder i zadziałało to dla mnie cudownie. Nie walczę już z moim kodem, ale jestem w stanie ulepszyć mój model widoku, tak jak potrzebuję, bez wpływu na model domeny.

+0

Zgadzam się z tym, że widok jest mniej zagracony, ale czy nie możemy tego typu abstrakcji funkcjonalności do modelu domeny zamiast modelu widoku? Powiedziałem to wcześniej, ale czy nie mogłem użyć funkcji DisplayAddress() w moim modelu domeny, która łączyłaby właściwości domeny takie jak Adres, Miasto, Stan i Zip? Baza danych tylko mapuje właściwości, a nie funkcje. – enamrik

+0

Oczywiście wszystko jest możliwe, tylko zależy od tego, w którą stronę chcesz iść. Mam wygenerowany dla mnie model domeny, więc naprawdę nie dotykam tego kodu. Jeśli używasz jakiejkolwiek formy ORM, to tak jest. Model widoku zapewniał mi największą elastyczność bez uszczerbku dla wydajności. –

+0

Przepraszam, ale nie skorzystałem z linku, który podałeś do tej pory. Doszedłem do wniosku, że decydowanie o tym, czy należy przyjmować model-model-widok-model trasy zależy od wymagań modelu domeny. Widzę, jak niektóre z moich obiektów modelu domeny korzystałyby z modelu widoku, podczas gdy inne tego nie zrobiły (chociaż mogłoby to kogoś zmylić - więcej o tym pomyślę). Tak czy inaczej, mam swoją odpowiedź. Dziękuje wszystkim! – enamrik

2

Czasami trzeba wyświetlać dane w określony sposób (np. Wyświetlać datę w formacie mm/dd/rrrr vs. rrrr/mm/dd) i często łatwiej jest zrobić tę właściwość w widoku i nie w modelu domeny, w którym miałbyś (lub powinieneś) mieć mapowanie do kolumny w twojej db.

+0

Dziękuję, to ma sens. Ale czy nie moglibyśmy po prostu wykonać funkcji na modelu domeny, aby to zrobić? Podobnie jak DisplayAddress(), która łączyłaby właściwości domeny, takie jak Adres, Miasto, Stan i Zip? Baza danych tylko mapuje właściwości, a nie funkcje. Czy ten pomysł jest pogwałceniem jakiejś filozofii projektowania? – enamrik

+0

W pewnym sensie tak. Możesz zrobić to wszystko w modelu domeny, jeśli naprawdę chcesz i będzie działać tak samo. Jednak nigdy nie widziałem, aby to działało bardzo dobrze z powodu konserwacji. Zazwyczaj widziałem takie rzeczy wprowadzane do modelu widoku (lub dowolnego modelu prezentacji, którego używasz). Tak naprawdę to tylko kwestia organizacyjna. :) – khr055

15

Kolejny dobry powód, aby ViewModel przywołuje duże zestawy danych. Można przekazać widok tablicy osób (Person[]), ale metadane, takie jak liczba stron, numer bieżącej strony, rozmiar strony nie powinny należeć do klasy Person.

Dlatego rozwiązanie PersonListViewModel rozwiązałoby ten problem.

+1

To bardzo dobry przykład. – Wuaner

+0

dziękuję! :-) –

2

Model ViewModel zawiera tylko te elementy, które są wymagane w widoku. Zwykle można je uważać za uproszczenie lub "spłaszczenie" bazowego modelu domeny.

myśleć o nich tak:

  • ViewModel: jest to dane, które należy uczynić w tej widzenia
  • modelu domeny: to wszystko jest informacja moja aplikacja potrzebuje o tej jednostce, aby wykonać całą jej funkcjonalność

Na przykład moja klasa zamówienia ma członka o nazwie Customer, który jest stowarzyszeniem composition, tzn. mój Zamówienie ma Klienta. Ten obiekt klienta ma członków, takich jak imię, nazwisko itp. Ale jak mam to pokazać w widoku "szczegółów" zamówienia lub listy zamówień i klientów, którzy je złożyli?

Cóż, używając ViewModel mogę mieć OrderListItemViewModel, który ma członka CustomerName i mogę odwzorować połączenie Firstname i Lastname z obiektu Customer na to. Można to zrobić ręcznie, lub korzystnie za pomocą Automapper lub podobnego.

Stosując to podejście, można mieć wiele modeli widoku zamówienia, które są specyficzne dla różnych widoków, np. Widok listy zamówień może wyświetlać nazwę klienta w inny sposób niż widok szczegółów zamówienia.

Kolejną zaletą ViewModels jest możliwość ograniczenia dodatkowych danych, które nie są wymagane od bazowego obiektu domeny w widoku, np. jeśli przeglądam listę zamówień, czy naprawdę chcę zobaczyć wszystkie dane kontaktowe klienta, dane rozliczeniowe itp.? Myślę, że to zależy od celu listy, ale prawdopodobnie nie.

2

trzeba pamiętać że Twój domain model classes są używane tylko internally; to znaczy, że nigdy nie są wysyłane do klienta . Właśnie do tego są używane typy modeli usług (typy widoku widoku) - reprezentują dane, które będą przechodzić między klientem a usługą.

Powiązane problemy