Wytyczne dotyczące struktury projektu w aplikacjach warstwowych MVVM, DDD i WPF

17

Usiłuję skonfigurować strukturę mojej aplikacji w VS i chcę „wypróbować” i w przyszłości udowodnić to na rozsądnym poziomie. Ta aplikacja będzie przepisem WPF starej aplikacji Winform, która nie przestrzegała żadnych konwencji. Bez warstw, poziomów, akronimów itp.

Jest to dość duża aplikacja dla przedsiębiorstw. Planowałem użyć Linq To SQL, ponieważ moje DB są i najprawdopodobniej zawsze będą MS SQL. Mam też istniejący zestaw umiejętności.

Chcę śledzić MVVM i DDD najlepiej jak potrafię, ale łączę je myląc się ze strukturą mojej aplikacji. Pozwól mi spróbować zilustrować kilkoma przykładami.

Gdy śledzę MVVM, moja struktura folderów może wyglądać następująco:

Views
Models
ViewModels
Helpers

ale jak to pasuje do uproszczonego podejścia warstwowego DDD, w którym moja struktura projektu może przypominać to:

MyApp.UI
MyApp.Domain
MyApp.Data

Czy mogę umieścić Modelswarstwę domeny, czy mam 3 wersje powiedz Person? Prowadzi to do kolejnego pytania, gdzie chciałbym umieścić moje repozytorium i odwzorowania obiektu DB na obiekt Domain? Zakładam, że dane ...

ViewsDostanę przejść w interfejsie użytkownika, ale ViewModelsteż?

Wreszcie, gdzie miałbym osadzić moją logikę biznesową?

Znalazłem następujące informacje na CodePlex, przykład DDD , i była to pewna pomoc, ale wydaje się, że jest przeznaczona dla aplikacji sieci Web, choć może to nie mieć znaczenia i przejawia się moja ignorancja.

Nie zrozum mnie źle, wiem, że mogę mieć tyle folderów i dzwonić do nich, jak tylko chcę. Próbuję dowiedzieć się, gdzie umieścić rzeczy, aby można je było skalować, a nie to, co niekoniecznie nazywają te miejsca.

Serce mojego pytania może być pokazane w ten sposób.
Mam tblPersonobiekt wygenerowany przez *.dbml. Jest to oczywiste i należałoby do mojej warstwy „Dane”.
Teraz miałbym Model, DTO, Model domeny lub jakkolwiek to się nazywa w osobnej warstwie (projekcie?) Person. Ja potrzebuję Mapperdo Personcelu tblPerson, że nie jestem pewien gdzie umieścić.
Potem będę miał ViewModel, na przykład, EditPersonktóry miałby swoje własne właściwości, z których pobiera, Personale być może również więcej.
Wreszcie miałbym widok związany z tym ViewModel ....

Aby wyjaśnić, że akapit jest wypełniony moimi założeniami i domysłami, mam nadzieję, że ktoś pomoże mi oczyścić powietrze lub zaoferować wgląd, aby za 6 miesięcy do roku nie kopać się bardziej niż potrzebuję.

Załamany paladyn
źródło
Linq To SQL nie nadaje się do większych projektów. Użyj Entity Framework lub innej ORM, takiej jak nHibernate. Ponadto, czy jest to aplikacja tylko dla klienta, czy klient-serwer?
Euforia
Jest to aplikacja tylko dla klienta WPF. Czy możesz również wyjaśnić, dlaczego uważasz, że L2S nie nadaje się do aplikacji średniej lub większej, gdy moim jedynym źródłem danych jest MS SQL?
Załamany Paladyn

Odpowiedzi:

5

MVVM jest wzorcem interfejsu użytkownika i jest używany w kliencie.

Części domeny w DDD, które są używane w kliencie, są prawdopodobnie (częścią) modelu

View i ViewModel są tylko klientami.

Umieszczam repozytoria w (lub w pobliżu) modelu, ponieważ synchronizują model z zapleczem.

Tak, wiele razy spowoduje to powstanie wielu klas Person w różnych przestrzeniach nazw. Mogą zacząć bardzo podobnie, ale po kilku iteracjach lub wydaniach mogą się bardzo różnić.

EDYTOWAĆ

Aby wyjaśnić część dotyczącą repozytoriów i wyjaśnić więcej na temat pozycjonowania logiki biznesowej

Jeśli tworzysz system, który zawiera osobnego klienta, repozytoria po stronie serwera / zaplecza mogą być używane w kliencie i serwerze. W kliencie w celu zapewnienia abstrakcji serwerów i na serwerze w celu uzyskania abstrakcji innych serwerów i źródeł danych. To tylko wzór.

Co do reguł biznesowych: jeśli używasz tych w kliencie, upewnij się, że egzekwujesz je również na serwerze. Nigdy nie ufaj klientowi. Reguły biznesowe w kliencie pozwalają na szybką weryfikację danych wejściowych i zapobiegają powrotom na serwer.

Myślę, że DDD należy do serwera i „przecieka” do klienta.

Eee nie
źródło
2

Masz właściwy kierunek w wyborze wzorca projektowego MVVM dla aplikacji WPF.

Do I put the Models in the Domain layer?

Tak, twoje modele można umieścić w domenie

Where would I put my Repository and mappings of DB Object to Domain Object?

Twoje repozytoria mogą być umieszczone w warstwie, w której umieszczona jest Twoja Domena. Twoje obiekty odwzorowujące (zwane również DTOs - obiekty transferu domen) powinny zostać umieszczone w warstwie usług, a możesz użyć potężnego narzędzia AutoMapper do łatwego mapowania obiektów domeny na DTO.

ViewModels also?

Twoje ViewModels powinny być umieszczone po stronie klienta (warstwa). Możesz konstruować swoje modele widoków z jednego lub więcej DTO, w zależności od twoich poglądów.

Jeśli chodzi o DDD , proponuję przeczytać o tym i wyjaśnić, że naprawdę potrzebujesz wzorca projektowania opartego na domenie. tutaj jest dyskusja, że 95% wszystkich aplikacji należy do kategorii „niezbyt dobrych do korzystania z DDD”.

Edycja: odniesienie zostało dodane powyżej, i dziękuję za @Den!

Jusubow
źródło
proszę komentować podczas głosowania.
Yusubov,
1
Fanboys DDD chcą go używać wszędzie. Odnośnik: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den
@ Den, dziękuję za link! planowałem tego poszukać.
Yusubov,
1

Zanim zagłębimy się w to, co się dzieje, porozmawiajmy o tym, co powinna robić każda warstwa.

Punktem sprzedaży MVVM jest powiązanie między widokiem a modelem widoku. Celem jest wyeliminowanie logiki w widoku.
Podobnie jak widok, model powinien być dość lekki i służył tylko do uzyskiwania dostępu do informacji (danych) niezbędnych do działania modelu widoku. Model może łączyć dostęp do różnych źródeł danych, ale nie powinien mieć logiki biznesowej. W większości przypadków wystarczy jeden magazyn danych. W niektórych przypadkach nie. Gdy tego nie zrobisz, należy użyć modelu, aby ukryć źródło danych z maszyny wirtualnej.

Domniemanym punktem MVVM jest to, że dane są już przechowywane, a twój projekt nie jest odpowiedzialny za utrzymanie swojej organizacji. Niektóre projekty mają szczęście, że udało mi się uniknąć tego założenia, większość projektów, nad którymi pracowałem, nie miała tyle szczęścia. Wystarczy powiedzieć, że Dane to kolejna warstwa, z którą będziemy musieli się zmagać.

Przedstawiłbym mój projekt w następujący sposób:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

i tę warstwę można dodać w razie potrzeby:

 project.Helpers

Oddzielam Pomocników od reszty stosu, aby nie pomylić go jako warstwy stosu aplikacji.

Oświadczenie: Nie jestem ekspertem od DDD, ale rozumiem ogólną istotę i widzę wartość tego podejścia.

Twoja domena będzie zestawem problemów, który rozważasz.
Te domeny modele będą odpowiadać przede wszystkim do ViewModels tworzonych; trochę w Widoku; i mały fragment w Model / DataStructs.

Jak to się ułoży?
JEŚLI masz możliwość zmiany istniejących struktur danych, to nowe, które utworzysz, powinny być skorelowane z problemem, który próbujesz rozwiązać. Masz obiekt klienta? Następnie powinieneś / powinnaś mieć tabele związane z klientem. Masz faktury lub produkty? Ta sama historia - należy utworzyć tabele i struktury odwzorowane na te obiekty biznesowe.

Domena będzie wyrażana za pośrednictwem obiektów ViewModel i widoków prezentowanych przez te obiekty. Jeśli musisz edytować rekordy klienta, będziesz mieć maszynę wirtualną do obsługi tego zadania.

Do twoich pytań:

  1. Nie próbuj nakładać DDD na MVVM. To po prostu nie zadziała. DDD nie jest wzorem układu, jest podejściem do przeglądania ogólnego problemu.
  2. Repozytorium i odwzorowania będą dostępne w projekcie albo w danych, albo w projekcie, odpowiednio do modelu.
  3. Nie posiadaj warstwy o nazwie UI, chyba że chcesz to nazwać project.Views.
  4. Logika biznesowa przejdzie do modelu widokowego.

źródło
1
OK, niektórzy, prawdopodobnie nieświadomi, odpowiedzą na pytania. (1) Czy zrobiłbyś każdy z nich osobnym projektem lub tylko folderami (np. Project.View itp.)? (2) DataStructs to miejsce, w którym należy umieścić * .dbml's lub Project.Data? (3) Więc twoim zdaniem nie miałbym Projektu. Domena? Widziałem, że kilkakrotnie użyłem, dlatego pytam.
Załamany Paladyn
@RefractedPaladin - 1) tylko foldery w projekcie. Możesz argumentować, że Data powinna być własnym projektem. Z punktu widzenia konserwacji, każdy sposób jest równoważny. 2) tak, dokładnie. 3) nie, nie miałbym folderu .Domain. IMO, naszym zadaniem jest mapowanie aplikacji do domeny problemów biznesowych. Domena przenika wszystkie warstwy projektu.