2012-06-26 4 views
5

Wether Używam Automappera lub mapowania ręcznego, które nie odgrywa żadnej roli.Nadal waham się używać ViewModels zamiast modelu do widoku

Wszystkie dane dla ReleaseViewModel muszą znajdować się na pierwszym miejscu w Wydaniu, ponieważ wypełnia się je warstwa dostępu do danych. 90% mojego modelu jest w ten sposób. Dlaczego narzut duplikowania wszystkiego?

Co z zasadą KISS i nadmierną inżynierią?

Oczywiście każde narzędzie do odpowiedniego zadania, ale bardzo często czytam na SO, że nie używanie ViewModels w asp.net mvc jest NO-GO.

Gdzie narysować linię? Czy należy używać ViewModels, gdy różnią się one do 50%, 75% lub 99% od moich modeli?

Mam Model Release:

public class Release 
    {  
     public int Id { get; set; }  
     public string Name { get; set; } 
     public string Author { get; set; } 
     public DateTime CreatedAt { get; set; } 
     public int FailedTestsCount { get; set; } 
     public int SucceededTestsCount { get; set; } 
     public int SumTestsCount 
     { 
      get 
      { 
       return SucceededTestsCount + FailedTestsCount; 
      } 
     } 
     public int SumTestingTime { get; set; } 
    } 

się ReleaseViewModel ViewModel:

public class ReleaseViewModel 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Required(ErrorMessage = "Name must not be empty.")] 
    [StringLength(30, ErrorMessage = "Enter max. 30 chars for a name.")] 
    [Remote("ReleaseExists", "Release", ErrorMessage = "This name already exists.")] 
    public string Name { get; set; }  
    public string Author { get; set; }  
    public DateTime CreatedAt { get; set; }  
    public int FailedTestsCount { get; set; }  
    public int SucceededTestsCount { get; set; }  
    public int SumTestsCount 
    { 
     get 
     { 
      return SucceededTestsCount + FailedTestsCount; 
     } 
    } 

    public int SumTestingTime { get; set; } 
} 
+0

Czy twoja klasa wydania jest DTO, czy jest to obiekt domeny z funkcjonalnością? – Jupaol

+0

jest to obiekt domeny. Nie mam wielu warstw, aby mieć potrzebę dto. – Pascal

+0

Dlaczego nie chcesz, aby Nazwa była wymagana i miała być mniejsza niż 30 znaków w modelu Twojej domeny? Mimo że model Twojej domeny nie może wyświetlić ładnego komunikatu dla użytkownika, może on nadal odmawiać przetworzenia, jeśli parametr ModelState.IsValid ma wartość false. Przynajmniej tak myślę, że powinieneś to zrobić, ale jestem nowicjuszem –

Odpowiedz

5

ViewModel to coś, co jest dla WIDOK:. przez większość czasu jest podobny do twojego modelu jednostki. Ale nie zawsze.

Spójrz na swój przykład. W swoim ViewModel masz atrybuty Remote i niektóre atrybuty sprawdzania poprawności. Tak więc sprawdzanie nazwy zdalnej jest czymś, co dodajesz, aby zapewnić lepszą obsługę użytkownikowi. Jest to specyficzne dla widoku.

Inny scenariusz, którego potrzebujesz, to Viewmodel dla ekranów, na których masz więcej niż jeden model. Np .: Masz jednostkę Entity i User i chcesz mieć ekran, na którym projekt może zostać dodany do użytkownika. Tak więc w tym przypadku można utworzyć model widoku, aby obsłużyć te modele. Nie należy używać ViewModels dla wszystkich elementów modelu. Utwórz go, gdy VIEW naprawdę go potrzebuje. Używam obiektów obiektów Model bezpośrednio w niektórych widokach, nie tworząc jednocześnie viewmodelu, ponieważ są one dokładnie takie same. Przykład: kraj/stan/miasto (Wyszukaj dane w tabeli. Nie dodawaj/edytuj)

+0

co oznacza komentarz "chcę wyświetlić tylko nazwę użytkownika!" ?? I tak zdalne sprawdzanie poprawności należy do przestrzeni nazw MVC, ale HEY robię aplikację mvc, więc to sprzężenie jest całkowicie OK. Czasami mam wrażenie, że klasa SelectListItem jest głównym argumentem myśliwców viewmodel, aby powiedzieć nam, że śmiertelny użytkownik potrzebuje modelu viewmodel, jeśli model jest ściśle powiązany z mvc, ale znowu jest aplikacją MVC. Myślę, że 99% wszystkich aplikacji dla przedsiębiorstw nie wykorzystuje ponownie ich domeny w innej aplikacji, takiej jak winforms/wpf, dlatego przestrzeń nazw web.mvc jest w moim modelu dobra. – Pascal

+0

Najbardziej podobał mi się ten komentarz: "Stwórz go, gdy WIDOK tego naprawdę potrzebuje". Zrobię to, a ponieważ robię to bardzo rzadko, robię to ręcznie. Mniejszy nakład montażu. Mniej sprzężeń ;-) – Pascal

+0

@Pascal: Ten komentarz oznacza: W moim ViewModelu będę posiadał właściwości, które są absolutnie potrzebne w moim widoku. Nie wszystkie właściwości jednostki Mój model (kolumny tabeli) – Shyju

1

Moi ViewModels prostu zawinąć model, a delegatem na nią 90% czasu. Mają własne zachowanie tylko wtedy, gdy muszę zmienić coś na temat zachowania modelu dla konkretnego przypadku użycia widoku. Posiadanie VM naprawdę znacznie ułatwia dodawanie zachowań, które są potrzebne tylko do celów wyświetlania, szczególnie jeśli takie zachowanie kolidowałoby z twoim modelem utrwalania (np. Dodawanie właściwości, które nie są Ci potrzebne).

Warto również zauważyć, że jest to całkiem możliwe, aby użyć narzędzia IoC jak zamek lub SpringFramework.net wygenerować zachowanie domyślne przekazywania na bieżąco, co zmniejsza ilość kodu, który trzeba napisać ręcznie. To znacznie zmniejsza "koszt duplikowania", więc nie jest tak źle, jak się wydaje na początku.

+0

"np. Dodawanie właściwości, których nie chcesz utrwalać)." to nie utrzymuj ich ?! Nie używam ORMappera. "Moje ViewModels po prostu zawijają model i przekazują go w 90% przypadków." Robisz to jak w modelu MVVM? To mnie zaskakuje. http://stackoverflow.com/questions/11213644/is-the-viewmodel-in-asp-net-comparable-to-the-viewmodel-in-wpf – Pascal

+0

Chyba używam czegoś takiego jak MVVM. Zawsze miałem pewien problem z "czystym" MVC i uważam, że paradygmat MVVM jest bardziej naturalny (nawet dla ASP.NET MVC). YMMV :-) –

2

Dlaczego narzut duplikowania wszystkiego?

Przede wszystkim, można by pomyśleć ja powielenie kodu, ale faktem jest, że nie jesteś, w przypadku, gdy to robią, masz poważny problem projektowania

I odkryli, że istnieje jedna zasada, że ​​gdy jej nie stosujesz, jest to prawdziwa przyczyna całego zła: SRP (Zasada Odpowiedzialności)

Być może dlatego, że jeszcze nie znalazłeś problemu, a może masz i ty właśnie załatałem twój kod. Odpowiedzialność za obiekt domeny jest zupełnie inna niż odpowiedzialność za przedstawienie danych użytkownikowi.

Model w MVC, powinien być klasą reprezentującą wszystkie dane, które widok musi renderować i nic więcej,. Musisz wypełnić ten model danymi z Twojej domeny. (lub w architekturze CQRS, z usług zapytań)

Jeśli stosujesz architekturę CQRS (przynajmniej nie musisz implementować obsługi zdarzeń ani korzystać z magistrali usług w celu oddzielenia poleceń od zapytań), to będzie dla ciebie bardziej zrozumiałe, odpowiedzialność obiektu zapytania jest zupełnie inna niż obiekt polecenia (akcja z twojej domeny).

Myślę, że źle zrozumiałeś zasadę KISS, a ona mówi o nadmiernej inżynierii kod lub YAGNI, nie oznacza to, że musisz użyć ponownie wszystko w aplikacji

Uwierz mi, nauczyłem się to zły sposób = (, jedynym kodem, który powinien być ponownie użyty jest kod infrastruktury, gdy mówimy o kodzie domeny, lepiej zawsze podążać zawsze za SRP

+0

"to nie znaczy, że musisz ponownie użyć wszystkiego w swojej aplikacji" SUCHA. – Pascal

+0

Nie łamiesz zasady DRY ... Byłem tam ... po prostu musisz zrozumieć ** rolę ** każdego komponentu gra. Jak tylko zrozumiesz to, i gdy tylko nauczysz się ** wyrażać role **, zobaczysz światło na końcu tunelu. Przeczytaj kilka artykułów z Udi Dahan. Miałem tę dyskusję wiele razy, a korzeń jest zawsze taki sam ... brak teorii projektu. A jeśli będziesz nalegał, aby podążać tą drogą, nauczysz się (tak jak ja) tego złego sposobu ... Myślę, że wpadniesz w zespół pocisku Srebrna ... – Jupaol

+0

Wiem, dlaczego powiedziałeś, że to nie psuje SODY. Ponieważ "wymieniasz" DRY z SRP tutaj. TAK podejście ViewMOdel ZAWSZE jest tym, czego wymaga SRP. ALE wolę zachować prostotę, zachować ją w praktyce i zachować ją zgodnie z aktualnymi wymaganiami. Czysty kod mówi, że nie należy go modyfikować, jeśli szansa nie wynosi 90%, jeśli jest to potrzebne. To jest praktyczne w praktyce, które rozumiesz? Myślę, że traktujesz to zbyt ekstremalnie. Że naprawdę nauczyłeś się złego sposobu, w jaki naprawdę musiałaś mieć dużą aplikację korporacyjną. Mamy tutaj 150 KB aplikacji asp.net/wcf, ale prawie nie potrzebujemy viewmodels. – Pascal

0

I sekundę wszystko, co mówi Shyju, zwłaszcza część o "kiedy potrzebujesz to".

Jeśli masz bardzo prosty projekt, w którym twoje klasy EntityModel znajdują się w tej samej bibliotece, co klasy ViewModel, możesz nie mieć potrzeby oddzielnego programu dMod ViewModel i możesz je anulować. Nie sądzę, aby ktokolwiek powiedział, że "zrobiłeś to źle, ponieważ używasz klas jednostek dla swoich modeli widoku, duma." Nie wiemy, jaki jest kontekst twojej aplikacji. Może to być całkowicie odpowiednie w twoim przypadku (ach).

Niektórzy z nas definiują EntityModels w zespole innym niż web - wystarczy zwykła biblioteka klasowa, która kompiluje się w bibliotece DLL - dla większych projektów. W takim przypadku często musimy zastosować specjalne atrybuty tylko do widoku, takie jak RemoteAttribute i HiddenInputAttribute w twoim przykładowym pytaniu. Jednak aby to zrobić bez użycia osobnej warstwy widoku dto oznacza, że ​​musimy dodać odniesienia do System.Web.Mvc.dll do biblioteki EntityModel, gdy w rzeczywistości ta biblioteka nie ma nic więcej do czynienia z siecią.

Należy pamiętać, że gdy ponownie używasz klas EntityModel w swoich projektach internetowych (np. Używasz ich jako modeli magazynowania i prezentacji), tworzysz ściślejsze powiązanie aspektów internetowych projektu z aspektami biznesowymi Twój projekt. Jeśli możesz to uzasadnić ze względu na koszt/budżet, czas, grupę docelową, zakres lub inne ograniczenia, zrób to i zignoruj ​​swoich krytyków, ponieważ nie widzą tak dużego obrazu jak ty.

0

jeśli twoja klasa wydania implementuje INotifyPropertyChanged i wszystkie inne rzeczy potrzebne do twojego widoku (sprawdzanie poprawności, polecenia, ...) to nie musisz używać viewmodel.ale jeśli nie ...

+0

Moja klasa Release jest używana w aplikacji mvc asp.net. Dlaczego powinno być INotifyPropertyChanged? – Pascal

+0

oh przepraszam, nie widziałem, że nie ma tagu WPF – blindmeis

Powiązane problemy