Wyznaczanie granic między modułami

0

Trochę w nawiązaniu do ostatniego wątku. Mam projekt Application podzielony na foldery (nie jestem pewien, czy można nazwać je modułami): Account, Customers, Products, Reviews, Orders i pewnie jeszcze kilka się znajdzie. Każdy produkt może mieć wiele recenzji, można aprobować poszczególne recenzje, być może też dodawać do nich komentarze. Każdy produkt ma też swoje zdjęcia (osobna tabela w bazie z metadanymi o nich) i oceny (oceny to niezależny od recenzji byt niemający z nimi nic wspólnego, choć nie jestem pewien, czy taki podział ma sens).

Pytanie: czy recenzje powinny stanowić oddzielny moduł? Z jednej strony, zdjęcia produktu też mają ID jak recenzje, a je wrzuciłem do Products, bo jakoś tak podświadomie mi tam pasowały. Z drugiej strony, recenzje mają referencje do kilku tabel-dzieci, co oznacza, że po wrzuceniu ich do Products moduł ten zacznie puchnąć. Ale jednak dalej są one "dziećmi" produktów, więc powinny być razem z nimi. Macie jakieś wskazówki, jak rozwiązywać tego typu problemy?

0

AFAIK moduł = csproj

1

Polecam w tym temacie książkę "Czysta architektura" Unlce Boba. Właściwie o tym jest cała książka ;)
Odpowiadając krótko.. (moduł chociaż w książce nazywają go komponentem) powinniśmy wydzielać używając reguł SOLID trochę na wyższym poziomie.

Wracając do Twojego przypadku. Uporządkowanie klas w katalogi w jednym projekcie zawsze jest dobrym pomysłem, aczkolwiek nie jest to wdzielanie komponentów. O wydzielaniu komponentów możemy mówić jeżeli zmiany w jednym z nich nie wymagają kompilacji innych. Czyli można to zrealizować tak jak później napisałeś, np. poprzez wydzielenie ich w osobne projekty.

I właśnie patrząc pod kątem zmian powinniśmy myśleć o wydzielaniu komponentów. Nie pod kątem tego czy jakiś obiekt ma pole ID. Tzn. na przykład jeżeli jakaś część aplikacji zmienia się częściej niż inna to warto ją wydzielić jako komponent. Trzeba jednak uważać, żeby po takim wydzieleniu komponent, który jest kluczowy dla aplikacji dalej nie miał silnych powiązań z mniej ważnym komponentem, który w dodatku często się zmienia. Tutaj pomagają interfejsy.

Ja bym tutaj jednal zostawił wszystko na początek w jednym projekcie jeżeli mówimy o obiekty jakie wypisałeś (Customers, Products, Reviews, Orders). Jest to bardzo mały projekt i bawienie się w kilka projektów, które i tak będą ze sobą bardzo powiązane nic ci nie da. Zwłaszcza, że tutaj mówimy o zależnościach, relacjach na poziomie DB. Poczekałbym na rozwój projektu.

Za to może warto pomyśleć o podziale na projekty patrząc na aplikację od strony warstw: dostęp do bazy, logika biznesowa, model (encje)

0

Hmm, po wrzuceniu recenzji do modułu z produktami dostałem to coś takiego. Może tak być? Jak dla mnie, nie wygląda to tak źle, jak sądziłem.

screenshot-20190420133129.png

3

@nobody01:

Widziałem podejście, gdzie Handler trzyma się fizycznie w / obok Command/Query aby:

a) nie zawalać projektu plikami, bo po co?

b) szybciej przeskoczyć do implementacji - tutaj chyba chodzi głównie o VS, że nie potrafi przeskoczyć do Handlera przy MediatRowym .Sendzie

Zniknęłyby Ci dwa foldery CommandHandlers oraz QueryHandlers

0

Moduł to pojęcie abstrakcyjne w językach zwykle jest wyrażany jako namespace. Nie bolą was oczy od tych procedur.? Dziwi mnie, że jeszcze nie przeszła ta moda na wpychanie wszędzie mediatora. :P

0

No cóż, na DDD za głupi jestem, więc pozostaje mi stary, biedny Transaction Script. :P Jak dla mnie, podejście command-handler świetnie pasuje do TS. Oczywiście wiem, że nie trzeba go używać, ale uważam, że bardzo upraszcza pisanie - nie trzeba się np. głowić nad tym, jak nazywać "serwisy" ani gdzie wydzielać kod. Dodatkowo jeśli napisze się jakieś HandlerBase pobierające z kontenera najczęściej używane zależności, to ilość nadmiarowego kodu jest dość mała (w większości handlerów nie trzeba nawet generować konstruktorów).

Chociaż takie podejście (pozdrawiam @neves) też jest dobre, wystarczy tylko zamienić repozytoria na jakieś DAO, jeśli nie chce się DDD ;)

1

Spoko, każdy pisze co mu się podoba. :P Jeśli TS to już bym wolał podział na procedury, czyli:

Product
--CreateProduct
----CreateProductQuery
----CreateProductQueryHandler
----CreateProductCommand
----CreateProductCommandHandler

A Review w Product:
Product
--Review
----etc...

2

Wracając do oryginalnego pytania czy *recenzje *powinny stanowić oddzielny moduł od produktu, nawet jeśli mają ID. Na bazie D&D w miarę łatwo podjąć tą decyzje, pytanie czy potrzebujesz mieć bezpośredni dostęp do *recenzji *z innych modułów czy nie, jeśli potrzebujesz stają się oddzielny modułem, jeśli nie potrzebujesz - będę dostępne jedynie za pośrednictwem produktu. Tzn żeby dostać recenzję, pierw odwołujesz się do produktu, a dopiero z niego możesz dostać się do recenzji. Wtedy ID traktuje się jako unikalne wyłącznie wewnątrz produktu, nie globalnie mimo że to baza relacyjna zapewnia.

Kontynuując przykład z poprzedniego printscreena; do encji Test można się dostać wyłącznie z repozytorium, do encji QuestionItem i QuestionsCatalogItem można wyłącznie się dostać poprzez Test, pomimo tego że mają własne ID.

title

0

@neves

Tzn żeby dostać recenzję, pierw odwołujesz się do produktu, a dopiero z niego możesz dostać się do recenzji. Wtedy ID traktuje się jako unikalne wyłącznie wewnątrz produktu, nie globalnie mimo że to baza relacyjna zapewnia.

Dlaczego tak.?

Nie patrzysz na zachowania.

Każdy produkt może mieć wiele recenzji, można aprobować poszczególne recenzje, być może też dodawać do nich komentarze

Product nie jest ci w żaden sposób potrzebny do pobrania DM-Recenzji. Ponad to Recenzje będą posiadały własne unikalne zachowania. Product może jedynie posiadać metodę fabrykującą Recenzje ze względu na wspólny Id.

To, że występuję jakieś powiązanie za pomocą identity field nie oznacza, że musisz to wszystko trzymać w jednym module ani, że musisz do jednej "encji" dostawać się przez inną "encje".

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