Domain-Driven Design – nie metoda a styl.…

Na temat pro­jek­to­wa­nia, mode­lo­wa­nia, ana­li­zy itp. napi­sa­no wie­le. Wiele razy też czy­ta­łem i obser­wo­wa­łem jak psu­je się pro­jek­ty tak zwa­ną opty­ma­li­za­cją, któ­ra jest jed­nak nie raz niczym innym jak upra­sza­niem pro­wa­dzą­cym czę­sto do kata­stro­fy pod­czas przy­szłej rozbudowy.

Często spo­ty­kam się z teza­mi, że mode­le two­rzo­ne w sty­lu DDD ([[Domain Driven Design]], ang. Projektowanie Zorientowane na Dziedzinę sys­te­mu) są mało opty­mal­ne. Najczęściej przy­ta­cza­nym przy­kła­dem jest kry­ty­ka agre­ga­tów ([[wzo­rzec pro­jek­to­wy Agregat]], obiekt biz­ne­so­wy mode­lo­wa­ny jako obiekt głów­ny i jego kom­po­nen­ty) jako mało wydaj­nych kon­struk­cji w przy­pad­ku zapy­tań o fil­tro­wa­ne i agre­go­wa­ne rapor­ty. Jest to praw­da ale wzo­rzec agre­ga­tu słu­ży do zarzą­dza­nia tymi obiek­ta­mi a nie do two­rze­nia zaawan­so­wa­nych wyli­czeń z uży­ciem ich wybra­nych atry­bu­tów. Zgodnie z DDD raczej nale­ży wte­dy zapro­jek­to­wać osob­ną kla­sę (agre­gat) będą­cą utwo­rzo­nym na boku” sto­sem danych do ana­liz. Czy tak się robi? Oczywiście, w dużych sys­te­mach sta­wia się dodat­ko­wą hur­tow­nie danych, któ­rych archi­tek­tu­ra jest przy­sto­so­wa­na do takich wła­snie zapy­tań, w mniej­szych pro­jek­tu­je się spe­cjal­na tabli­cę danych do takich raportów.

Niestety spo­ty­kam się czę­sto z uprasz­cza­niem dobrych mode­li bo będzie się lepiej rapor­to­wa­ło”. Czy lepiej to się oka­że w prak­ty­ce zaś model zepsu­ty” (naj­czę­ściej opty­ma­li­za­cja pole­ga na uprasz­cza­niu kon­struk­cji agre­ga­tu) sta­je się póź­niej nie raz nie­moż­li­wy do rozbudowy.

Właśnie mam w ręku książ­kę [[Joshua Blocha Java Efektywne Programowanie]] (kupi­łem by poczy­tać co robią pro­gra­mi­ści a nie pro­gra­mo­wać ;)))) i tam jest roz­dział o opty­ma­li­za­cji, a w nim super sen­ten­cja: sta­raj się pisać pro­gra­my popraw­ne a nie szyb­kie, po szcze­gó­ły tej myśli odsy­łam do książ­ki… Jakakolwiek opty­ma­li­za­cja na eta­pie pro­jek­to­wa­nia jest przed­wcze­sna, dopie­ro po skom­pi­lo­wa­niu i testach nale­ży oce­nić czy pro­gram jest za wol­ny, bo może nie jest …

Czemu lubię i pole­cam styl DDD? Bo nawet jak nie zna­my przy­szłych zmian (nowych wyma­gań) to na pew­no pro­jekt będzie się dało roz­bu­do­wać zamiast zmie­niać. Dlaczego? Bo jeśli pro­jekt dobrze mode­lu­je” rze­czy­wi­stość to zna­czy, że jeśli tyl­ko coś zmie­ni się w tej rze­czy­wi­sto­ści będzie moż­li­we to, do takie­go same­go odwzo­ro­wa­nia w pro­jek­cie. (tu pole­cam tak­że arty­kuł ze stron devlab​.pl o tak zwa­nych ValueObject): Ważne jest tak­że prze­strze­ga­nie her­me­ty­za­cji, któ­ra tak­że mode­lu­je rze­czy­wi­stość. Innymi sło­wy jest tyl­ko jeden spo­sób by poznać lub zmie­nić zawar­tość mojej tecz­ki: popro­sić mnie”. Optymalizacja pole­ga­ją­ca na udo­stęp­nia­niu danych obiek­tów wprost, jeśli nie (o zgro­zo) bez­po­śred­nio z innych obiek­tów, to z pomo­cą ope­ra­cji get/set (bez­po­śred­nie pyta­nia o kon­kret­ne atry­bu­ty i ope­ra­cje na nich) mamy na tacy to co powin­no być chro­nio­ne. Skutki są takie, że być może nie­co upro­ści­li­śmy kod ale jego przy­szła roz­bu­do­wa i kon­ser­wa­cja raczej będzie kosz­ma­rem. Zapewne wie­lu z Was spo­tka­ło się z przy­pad­kiem, popra­wie­nia (uzu­peł­nie­nia) jakiejś funk­cjo­nal­no­ści powo­du­ją­cą lawi­nę błę­dów w innych. To jeden z typo­wych efek­tów łama­nia zasa­dy hermetyzacji.

Polecam arty­kuł z MSDN (cytat poni­żej), dodam że DDD to raczej styl ana­li­zy i pro­jek­to­wa­nia a nie meto­dy­ka bo nie ist­nie­je recep­ta na ana­li­zę i mode­lo­wa­nie. Trzeba zro­zu­mieć to co się mode­lu­je i odwzo­ro­wać w posta­ci mode­lu w imple­men­to­wa­nym opro­gra­mo­wa­niu. Porównanie z jaski­nią Platona jest doskonałe :):

Możecie przy­rów­nać [[teo­rie o Jaskini Platona]] do for­mu­ły mode­lo­wa­nia DDD. Wiele z tych zale­ceń poma­ga nam zbli­żyć się ide­al­ne­go mode­lu w ogó­le. Droga pro­wa­dzą­ca do two­rzo­ne­go kodu zale­ży od głów wie­lu eks­per­tów dzie­dzi­no­wych i pro­jek­tan­tów, spon­so­rów pro­jek­tu, wyma­gań bran­ży w któ­rej pra­cu­je­my. Dlatego ma ogrom­ny sens patrze­nie (razem) na pro­jek­to­wa­ny sys­tem (opro­gra­mo­wa­nie) jak na cie­nie odwzo­ro­wu­ją­ce rze­czy­wi­stość na ścia­nie jaski­ni przed jej miesz­kań­ca­mi. (źr. An Introduction To Domain-Driven Design.)

Na koniec mała uwa­ga dla zwo­len­ni­ków metod zorien­to­wa­nych na przy­pad­ki uży­cia. Projektowanie na bazie [[sesji JAD]] i kolek­cjo­no­wa­niu przy­pad­ków uży­cia bar­dzo czę­sto pro­wa­dzi do bar­dzo kosz­tow­nych ana­liz i opa­słych doku­men­tów, gdzie odkry­wa­ne potem w pro­to­ty­pach nowe wyma­ga­nia nisz­czą budżet i har­mo­no­gram pro­jek­tu, jeśli nie wyra­ża się na nie zgo­dy nisz­czą przy­dat­ność pro­duk­tu. Piękną meta­fo­rę przy­to­czył [[Martin Fowler]]:

AllTopics

Wyobraźmy sobie kogoś, kto chce napi­sać pro­gram symu­lu­ją­cy part­ne­ra do gry w sno­oke­ra. Problem ten może zostać opi­sa­ny przy­pad­ka­mi uży­cia opi­su­ją­cy­mi cechy tej gry sce­na­riu­szem: Gracz ude­rza bia­łą kulę, któ­ra prze­miesz­cza się z kon­kret­ną pręd­ko­ścią, ta po okre­ślo­nym cza­sie ude­rza czer­wo­ną kulę pod okre­ślo­nym kątem, ude­rzo­na czer­wo­na kula prze­miesz­cza się na pew­ną odle­głość w pew­nym kie­run­ku.” Możesz sfil­mo­wać set­ki tysię­cy takich ude­rzeń, zare­je­stro­wać (sce­na­riusz) para­me­try każ­de­go ude­rze­nia i jego skut­ki. Jednak tą meto­dą i tak nie stwo­rzysz nawet dość dobrej symu­la­cji. Aby napi­sać na praw­dę dobrą grę, powi­nie­neś raczej zro­zu­mieć pra­wa rzą­dzą­ce ruchem kul, ich zależ­ność od siły i kie­run­ku ude­rze­nia, kie­run­ku itp. Zrozumienie tych praw pozwo­li Ci znacz­nie łatwiej napi­sać dobre opro­gra­mo­wa­nie.” (źr. [[Analysis Patterns. Reusable Object Models, Martin Fowler, Addison-Wesley, 1997]], wtrą­ce­nia moje).

Powyższy cytat, moim zda­niem powi­nien sobie wziąć do ser­ca każ­dy dobry ana­li­tyk i pro­jek­tant. Powiem też, że dla mnie sam ten cytat wart był ceny książ­ki. To jest wła­śnie spo­sób myśle­nia, któ­ry gorą­co pole­cam i sam sto­su­ję. Z innej książ­ki: przed­mio­tem ana­li­zy jest to co ogól­ne, rze­mio­sło w szcze­gó­łach jako narzę­dzie pro­jek­to­wa­nia się nie sprawdza.

Na koniec pole­cam tak­że inny cie­ka­wy arty­kuł koń­czą­cy się słowami:

… gdy sytu­acja robi się zło­żo­na, dobrze jest zde­cy­do­wać się na podej­ście w sty­lu DDD, ponie­waż jest dużo bar­dziej czy­tel­niej­sze i lepiej odpo­wia­da ska­li skom­pli­ko­wa­nych i dużych apli­ka­cji. (źr. La Gal?re / Propaganda Kapitana Pazura ? Blog Archive ? O wali­da­cji słów kilka).

Programistom i nie tyl­ko, pole­cam cie­ka­wy arty­kuł Sławka Sobótki z SDJ na temat DDD.

Inne artykuły na podobny temat

Komentarze

  1. Mateusz Kurleto 3 marca 2011 at 00:36

    Wiele w tym praw­dy. Warto jed­nak­że zauwa­żyć, że wska­zu­jąc pro­ble­my z opty­ma­li­za­cją tak na praw­dę mówisz o jej kary­ka­tu­rze. Optymalizacja win­na pro­wa­dzić do subiektywnie(z punk­tu widze­nia pro­jek­tu) lepszego(szybszego, łatwiej­sze­go dla użyt­kow­ni­ka) osią­gnię­cia tych samych celów, przy zacho­wa­niu wyma­gań (w tym ogra­ni­czeń i łatwo­ści modyfikacji).
    Dobra opty­ma­li­za­cja na eta­pie pro­jek­to­wa­nia pozwa­la zacho­wać zale­ty DDD, czy inne para­me­try przy­ję­te w wyma­ga­niach. Rozwiązań jest wie­le – ot choć­by odpo­wied­nie agre­ga­ty dla fil­trów, lub agre­ga­cje o poziom niżej w tak­so­no­mii. Ale to już zbyt szcze­gó­ło­we kwestie:)

  2. Michał Mroczek 5 marca 2011 at 21:52

    Wzmianka o jaski­ni Platona to strzał w dzie­siąt­kę. Chyba muszę zacząć pisać arty­ku­ły, bo ja wpa­dłem na to już parę lat temu 🙂

  3. Michał Drozdowicz 15 marca 2011 at 12:37

    Jeśli cho­dzi o DDD i pro­blem rapor­to­wa­nia czy pre­zen­to­wa­nia danych spo­mię­dzy agre­ga­tów oraz opty­ma­li­za­cję wydaj­no­ści, to war­to spoj­rzeć dodat­ko­wo na wzo­rzec CQRS (Command-Query Responsibility Segregation). W skró­cie cho­dzi o to, że roz­dzie­la­my w sys­te­mie odpo­wie­dzial­ność za prze­twa­rza­nie komend zmie­nia­ją­cych stan sys­te­mu od czę­ści wycią­ga­ją­cej dane do pre­zen­ta­cji. Efekt jest taki, że model dzie­dzi­ny (w opar­ciu o DDD) odwzo­ro­wa­ny jest w czę­ści prze­twa­rza­ją­cej komen­dy, zaś struk­tu­ra danych w czę­ści Query jest mak­sy­mal­nie uprosz­czo­na i odpo­wia­da stric­te potrze­bom wido­ków pre­zen­to­wa­nych użytkownikowi.

    • Jarek Żeliński 15 marca 2011 at 18:55

      Czy to przy­pad­kiem nie skut­ku­je pro­duk­tem”: Model Dziedziny ope­ra­cyj­ny plus hur­tow­nia danych na boku” do raportowania?

    • Michał Drozdowicz 16 marca 2011 at 08:59

      Nie do koń­ca. Po pierw­sze, to źró­dło danych nie musi agre­go­wać danych z róż­nych sys­te­mów, więc nie jest potrzeb­ny zło­żo­ny ETL. Po dru­gie, zwy­kle te dane nie są wyko­rzy­sty­wa­ne do przy­go­to­wy­wa­nia skom­pli­ko­wa­nych rapor­tów histo­rycz­nych z moż­li­wo­ścią ana­li­zy wie­lo­wy­mia­ro­wej, a raczej jako część zwy­kłe­go sys­te­mu trans­ak­cyj­ne­go więc zamiast sys­te­mu OLAP wystar­czy baza danych (rela­cyj­na lub nie).

    • Jarek Żeliński 17 marca 2011 at 07:48

      pisząc hur­to­nia danych” mia­łem raczej na myśli dedy­ko­wa­ną do rapor­to­wa­nia struk­tu­rę a nie od razu ETL i wie­lo­wy­mia­ro­we mode­le danych, rzecz w tym, by pro­wa­dzić” rów­no­le­gle pła­ską tabe­lę do rapor­to­wa­nia. Jednak zapew­ne potrzeb­ne będzie osza­co­wa­nie na ile waż­na jest funk­cja ope­ra­cyj­na agre­ga­tów a na ile raportowa…

    • Michał Drozdowicz 17 marca 2011 at 10:24

      Ok. W takim razie mówi­my o tym samym 🙂 Rzeczywiście skut­kiem jest zazwy­czaj osob­na baza danych pod zapytania.

Dodaj komentarz

Twój adres email nie zostanie opublikowany

Komentuj i zadawaj pytania autorowi.

Identyfikator *
E-mail *
Witryna internetowa

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.