Czy to dobry pomysł, aby dodać ViewModel dokładnie tak samo jak Model

16

W moim rozwiązaniu mam następujące warstwy:

  1. App.Domain
  2. App.Service
  3. App.Core (może to się nazywa App.DataLayer)
  4. App.Web

Wzorzec projektowania oprogramowania to nie moje pytanie, mam następujący model w Domain

public class Foo {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Chcę użyć tego modelu w widoku (na przykład na stronie głównej) ORAZ chcę użyć Id, Name & Value, więc jeśli chcę utworzyć ViewModel, dodam następujące:

public class FooViewModel {
    public int Id {get;set;}
    public int Name {get;set;}
    public int Value {get;set;}
}

Czy to dobry pomysł? lub po prostu użyj Foozamiast FooViewModel?

Mehdi Dehghani
źródło
Nie jestem pewien, czy to rozumiem. Czy Modelzwykle nie jest to przekazywane View? Dlaczego dokładnie musisz odtworzyć pola Modelw View? Jeśli celem jest rozdzielenie obaw, to MVCw jakich okolicznościach chciałoby się zrobić to samo z Modeli View? Jeśli ViewModeltak, dlaczego nie, rozszerzając / komponując oba Modeli View?
null
proszę przeczytać moje komentarze do odpowiedzi @ svidgen
Mehdi Dehghani,
Mam pokrewny problem - gdy sprawdzanie poprawności (wymagany atrybut) w modelach (i w bazie danych) stwierdza, że ​​pewne wartości muszą zostać wprowadzone - ale w widokach te wartości nie muszą być - więc jestem zmuszony skopiować niektóre pola z modele w modelu widoku - zamiast bezpośredniego odwoływania się do modelu. Jednak po zastanowieniu prawdopodobnie jest to w porządku i faktycznie nie narusza SUCHEGO, ponieważ są one przeznaczone do różnych celów (i tak niezbyt mocno).
niico

Odpowiedzi:

20

Początkowo może to wyglądać na naruszenie zasady DRY, ale twierdzę, że „podobny, a nawet identyczny, kod” niekoniecznie musi „powtarzać się”, jeśli robi coś innego lub jest w stanie zmienić się niezależnie. W przypadku modeli widoku kod określa to, co widzi „klient”, niekoniecznie podmioty i operacje, o których mówi biznes. Często ujawniasz klientowi modele lub interfejs, które są „nawiasem mówiąc identyczne”. Możesz zmienić zasady i warunki biznesowe lub terminologię użytkownika końcowego niezależnie od siebie.

Więc zwrócę ci pytanie. Jeśli domena ulegnie zmianie, czy klienci „wersji 1” mogą nadal korzystać ze starych interfejsów? Czy kiedykolwiek ujawnisz warunki lub operacje w interfejsie, które nie są częścią „podstawowych reguł biznesowych”? I wzajemnie?

Tego rodzaju pytania mają na uwadze, jeśli „funkcja” twojego widoku ma na celu wyłącznie ujawnienie podstawowego modelu domeny, tak, wygląda na to, że narusza zasadę DRY.

Należy również pamiętać, że odsłonięcie widoku, który zmienia się bardziej naturalnie wraz ze zmianami modelu, można również osiągnąć w niektórych językach z atrybutami elementu i refleksją. (Lub z mniejszą liczbą powtórzeń poprzez inne wyczyny sprytu ... Ale „spryt” często nie usprawiedliwia powtórzeń, które oszczędzają.)

svidgen
źródło
Ładnie wspomniane notatki (głosuj na to), jak powiedziałem jako komentarz do poprzedniej odpowiedzi, mówię o ogólnym celu, obrazowaniu, może kilka dni później postanowiłem dodać nowe pole / właściwość Foo, więc jeśli użyłem Foojako ViewModel również klient otrzyma nową właściwość, więc co z tego, jeśli ta nowa była polem bezpieczeństwa (może prawda / fałsz za pozwolenie lub coś takiego), co powinienem zrobić?
Mehdi Dehghani,
@mehdi musisz dokładniej określić, jakie pole chcesz dodać i dlaczego Twoim zdaniem należy do niego lub go nie należy. Lub ogólnie, jakie są obawy.
svidgen,
@mehdi dla jasności, jeśli martwisz się, że użytkownicy końcowi zmienią wartość bezpieczeństwa, twoja domena po prostu nie powinna pozwalać użytkownikom na zapisywanie rzeczy, których nie są upoważnieni do zapisywania
svidgen
Dlaczego korzystamy z ViewModels? jest kilka powodów, jak wiemy, jednym z nich jest bezpieczeństwo, na przykład, User edit formnie musimy przekazywać IsAdminpola do klienta, aby zapewnić bezpieczeństwo tego pola, więc o to się martwię. Przepraszam za mój zły język angielski.
Mehdi Dehghani,
1
Innymi słowy, myślę, że oryginalne pytanie jest pełne. Pytanie, które próbujesz znaleźć w komentarzach tutaj, to kolejne pełne pytanie. Komentarze nie są dobrym sposobem na uzyskanie dobrych, wysokiej jakości odpowiedzi.
svidgen,
2

Miałbym model widoku zawierający tylko jedną właściwość, instancję Foo. W ten sposób nie naruszasz DRY zgodnie z jakąkolwiek jego definicją, jeśli zmieni się Foo, twój model widoku automatycznie zobaczy zmianę i pozostaniesz wolny od bezpośredniego powiązania modelu widoku z modelem.

Jeśli jutro będzie potrzeba, aby widok pokazywał coś innego, a także Foo, możesz po prostu dodać nową właściwość, a zamiary modelu widoku nadal będą jasne, zawiera ona Foo i coś innego, czego nie będziesz mieć mieszanka właściwości Foo z niepowiązanymi innymi właściwościami.

Nie pomyślałbym o twoim modelu widoku jako modelu FooViewModel, pomyślałbym o tym pod względem tego, co widok ma wyświetlać. Jeśli wyświetla tylko jeden Foo, wówczas model widoku zawiera jedną właściwość, Foo.

Nie jestem pewien, czy wyjaśniłem to jasno. Jeśli nie, daj mi znać, a spróbuję przeredagować to, gdy się obudzę!

Avrohom Yisroel
źródło
-2

Powiedziałbym, że użycie FooViewModelw ten sposób narusza zasadę SUCHEGO. Kiedy musisz dokonać zmiany, Foomusisz również dokonać zmiany w FooViewModel. Myślę, że lepiej byłoby, gdybyś był po prostu użyty Foojako model twojego widoku. Rozważę model widoku, jeśli chcesz wyświetlić rzeczy z Foo i coś innego. Na przykład powiedz, że musisz renderować niektóre informacje Foozi Bar.

zero_dev
źródło
Proszę, powiedz mi, jeśli zdecyduję się dodać kolejne pole / właściwość do Foo, więc ponieważ użyłem również Foojako ViewModel, więc muszę przekazać to nowe pole również do widoku, myślę, że to nie jest naprawdę dobra okazja, co myślisz ?
Mehdi Dehghani,
Nie widzę nic złego w tym, że widok używa tylko podzbioru danych ujawnionych przez model. Myślę, że większym faulem jest połączenie między Fooi FooViewModel. Zasadniczo modyfikowanie wielu plików dla pojedynczej zmiany logicznej nie jest dobrym pomysłem.
zero_dev
Co jeśli to dodane pole było polem bezpieczeństwa, takim jak pewna true/falsewartość pozwolenia lub coś w tym rodzaju.
Mehdi Dehghani,
Nie musisz ujawniać takich pól w samym widoku, ale nadal powinieneś upewnić się, że reszta kodu nie pozwala użytkownikowi na zmianę poziomu bezpieczeństwa, na wypadek, gdyby złośliwy użytkownik próbował wprowadzić taką zmianę POST.
Graham,
Wygląda na to, że byłby otwarty na masowe ataki przydziału
James