Czy tworzycie niemutowalne ViewModele?

0

Czy tworzycie niemutowalne ViewModele? Jeśli tak, to czy wyglądają one tak jak tu? Co, gdy liczba parametrów w konstruktorze zwiększy się? Używacie named parameters (nie wiem, jak się one nazywają po polsku) i po problemie?

public class CreatePostViewModel
    {
        public string Body { get; private set; }

        public int TopicId { get; private set; }

        public string AnonymousAuthorName { get; private set; }

        public CreatePostViewModel(
            string body, 
            int topicId, 
            string anonymousAuthorName = null)
        {
            Body = body;
            TopicId = topicId;
            AnonymousAuthorName = anonymousAuthorName;
        }
    }
5

Jak dla mnie to tylko struktura danych do przesłania, więc nie widzę sensu w traceniu czasu na tworzenie im konstruktorów.

4

A tak w ogóle co mają wnieść niemutowalne view modele :)?

Swoją drogą w C# 8.0 mają się pojawić rekordy, i wtedy tworzenie niemutowalnych struktur będzie bajecznie proste:
https://blog.cdemi.io/whats-coming-in-c-8-0-records/

0

A co w ogóle sądzicie o niemutowalnych DTO? Sądząc po tematach na tym forum, to w środowisko Javowców jest o nich dość głośno. I czy w ogóle DTO/ViewModele to powinny być struktury czy klasy?

1

Jakoś do mnie te niemutowalne DTO jeszcze nie dotarły :), w typowych aplikacjach biznesowych niemutowalność zwykle się pojawia przy Value Object.

Jeśli chodzi o wybór pomiędzy konstrukcją języka struct czy class, zawsze zaczynaj od class, struct jest tylko dla bardzo wyjątkowych okoliczności.

1

Przywołany.
Mutowalne DTO? Po co?

1

Nie chodzi o to że ta mutowalność jest nam do czegoś potrzebna, tylko o to że jeśli używamy DTO zgodnie z przeznaczeniem to nic złego nie powinno się stać nawet gdyby doszło do mutacji.
No chyba że te DTO są używane do komunikacji między wątkowej, albo piszemy funkcyjnie, wtedy rzeczywiście jest sens robienia ich niemutowalnymi.
A tak, póki nie ma rekordów w C#, to nie dostrzegam zysku usprawiedliwiającego te dodatkowe linijki kodu.

0

Jeśli robię "DTO" jako Result jakiegoś Query Servis'u i to idzie prosto jako Json na ekran. To robię konstruktor. Nie widzę sensu w ustawianiu tego przez setery tylko dlatego że w jakimś tutorialu pokazali że trzeba do tego AutoMappera używać.

Z książek DTO znam jako obiekty do komunikacji pomiędzy DM czy kontekstami. Ale powszechnie przyjęte jest że wszystko co zwraca serwis nazywa się DTO.

0
neves napisał(a):

Nie chodzi o to że ta mutowalność jest nam do czegoś potrzebna, tylko o to że jeśli używamy DTO zgodnie z przeznaczeniem to nic złego nie powinno się stać nawet gdyby doszło do mutacji.

Jeśli jest to obiekt zbiorczy, który ma zmniejszyć ilość wysyłanych żądań. Jaka jest pierwotna funkcja DTO to pewnie nic by się złego nie stało.

1

Zysk z konstruktora jest taki, że jak mamy tam 2 parametry i dojdzie 3ci - to nie zapomnimy ustawić. Bo się nie skompiluje. A setter zawsze zawodny jest.
Dodatkowo nie wiem o co chodzi z tym dodatkowym kodem - akurat bardzo prostacka niemutowalna klasa to nawet mniej kodu niż mutowalna. W javie ani setterów, ani getterow nie robię. Tylko konstruktor i pola final. Na DTO starcza. (Do ciekawszego fp nie starczy, ale tu nie o tym mowa).

1

Czy to ma znaczenie skoro tam nie ma logiki biznesowej więc jedyne co można zepsuć to nadpisac jakąś wartość?

0
Aventus napisał(a):

Czy to ma znaczenie skoro tam nie ma logiki biznesowej więc jedyne co można zepsuć to nadpisac jakąś wartość?

No nie, ale teraz jest prościej:

public class CreatePostViewModel
    {
        public string Body { get; private set; }
 
        public int TopicId { get; private set; }
 
        public string AnonymousAuthorName { get; private set; }
 
        public CreatePostViewModel(PostPersistence post, bool anonymousAuthorName)
        {
            Body = post.Body;
            TopicId = post.TopicId;
            AnonymousAuthorName = anonymousAuthorName;
        }
    }
0

Zagram adwokata diabla i podam kontrargument do swojego poprzedniego postu. Argumentem przemawiajacym za niemutowalnymi view modelami i przekazywaniem danych tylko poprzez konstruktor- ktory swoja droga jest kultywowany w moim obecnym projekcie- jest to ze konstruktor definiuje kontrakt i wyraznie wskazuje co musi zostac przekazane. Nie ma miejsca na zapomenienie o jakiejs wartosci, tak samo jak nie ma niejasnosci ktora wartosc jest opcjonalna a ktora nie (swoja droga to tez mozna osiagnac przez konstruktor za pomoca typow opcjonalnych). W projekcie w ktorym obecnie pracuje uwaza sie ze benefity sa wieksze niz minus plynacy z dluzszej listy parametrow.

0
jarekr000000 napisał(a):

Zysk z konstruktora jest taki, że jak mamy tam 2 parametry i dojdzie 3ci - to nie zapomnimy ustawić. Bo się nie skompiluje. A setter zawsze zawodny jest.

Jest tak zawodny jak dobre i sensowne mamy pokrycie testami.

Problem z DTO to nie jest problem "mamy 2 parametry i dochodzi trzeci", tylko "jest 17 parametrów i dochodzi 6".

Dodatkowo nie wiem o co chodzi z tym dodatkowym kodem - akurat bardzo prostacka niemutowalna klasa to nawet mniej kodu niż mutowalna. W javie ani setterów, ani getterow nie robię. Tylko konstruktor i pola final. Na DTO starcza. (Do ciekawszego fp nie starczy, ale tu nie o tym mowa).

No, a C# nie jest taki magiczny jak Java, i nie ma ujemnych linii kodu. Napisanie konstruktora, to jednak więcej kodu niż brak konstruktora.

I taki konstruktor do DTO/VM, to po prostu taki sztuczny twór (co sugeruje płacenie od linijki), który będzie się często zmieniał i irytował, a nie da żadnej wartości dodanej. DTO/VM to "obiekcik" (bo obiekt to to nie jest, przynajmniej nie według definicji OOP), który żyje w aplikacji bardzo krótką chwilę, jest tworzony w jednym miejscu, a następnie przesyłany przez jakieś medium. Nie ma nawet okazji go skutecznie zmutować.
No chyba, że ktoś ma architekturę DTO na twarz i pchasz, bierze np. taki token zwrócony przez PayPala i przepuszcza go przez 40 klas w swoim systemie, żeby go obudować w dane zamówienia, płatności, klienta, itd. No, ale przy takim podejściu, to konstruktor też nie pomoże. Nic już nie pomoże.

Tak naprawdę, to cały problem wynika głównie z tego, że języki, którym posługuje się znaczna część branży są upośledzone i mają jedno słowo class, którego trzeba używać do definiowania skrajnie różnych rzeczy: algorytmów, orkiestratorów, krotek, rekordów, itd.

0

Właśnie zrozumiałem, że ASP.NET nie jest w stanie (domyślnie!) zbindować niemutowalnych ViewModeli. Jako że nie mogę już edytować, proszę moderatorów o zaznaczenienie tego w moim pierwszym poście, aby nie wprowadzać nikogo w błąd.

0

Tak naprawdę, to cały problem wynika głównie z tego, że języki, którym posługuje się znaczna część branży są upośledzone i mają jedno słowo class, którego trzeba używać do definiowania skrajnie różnych rzeczy: algorytmów, orkiestratorów, krotek, rekordów, itd.

Na całe szczęście jest dobry język programowania jak Kotlin w którym sa też data classy np.

data class User(val name: String = "", val age: Int = 0)

Data class jest z defaultu final, val oznacza że pole jest finalne. Data classy mają metodę copy:

val jack = User(name = "Jack", age = 1)
val olderJack = jack.copy(age = 2)

A co do mutowalności pamiętam ile razy się wkurzałem że musiałem robić jakieś dziwne kopie java.util.Date (niestety zdarzalo mi się pracowac z tym raczyskiem). Może np. być tak że jak mapujemy część danych np. z jakiejś encji do do DTO to przez przypadek zamiast settera na DTO wywołamy settera na encji itd.

1 użytkowników online, w tym zalogowanych: 0, gości: 1