Dom bez planów

CQRS czyli kto, co i jak zamawia i dostarcza

Poprzedni arty­kuł koń­czy­ły słowa:

Tak więc jest to moim zda­niem dro­ga do mode­lo­wa­nia wyma­gań meto­dą ?tak to ma dzia­łać? a nie tyl­ko ?tak to ma wyglą­dać?, bo to dru­gie jest przy­czy­ną wie­lu problemów?

Wielu deve­lo­pe­rów zacie­kle bro­ni się przed tezą, że wyma­ga­nia to tak­że ?żąda­na reali­za­cja logi­ki biz­ne­so­wej?, ocze­ku­ją wyłącz­nie zesta­wu wyma­gań funk­cjo­nal­nych i poza-funk­cjo­nal­nych. Jest to moim zda­niem źró­dło dwóch ryzyk:

  • jeże­li zamó­wie­nie jest opi­sem czar­nej skrzyn­ki tak na praw­dę nie wie­my do dosta­nie­my jako jej realizację,
  • jeże­li auto­rem reali­za­cji jest dostaw­ca, pozo­sta­je mu nie­zby­wal­ne pra­wo do pro­jek­tu tej realizacji.

Dlatego war­to, jako wyma­ga­nie prze­ka­zać pro­jekt tak zwa­nej ?bia­łej skrzyn­ki?, bo zabez­pie­cza to nas przed powyż­szy­mi ryzy­ka­mi. (Wzorzec ana­li­tycz­ny Boundary Control Entity).

Czemu tak bro­nię tej tezy? Zarzuty deve­lo­pe­rów wobec mnie to: wymu­szasz imple­men­ta­cję a to rola pro­jek­tan­ta”. Jest to nie praw­da, bo pro­jek­ty wyma­gań zawie­ra­ją­ce wewnętrz­ną logi­kę to jesz­cze nie imple­men­ta­cja, ale na pew­no jest to ocze­ki­wa­nie kupu­ją­ce­go opro­gra­mo­wa­nie. Gdybym kupo­wał samo­chód nie chciał bym, by mi ktoś powie­dział, że wol­no mi powie­dzieć tyl­ko jak będę do nie­go wsia­dał, wysia­dał i po co, że będę zgod­nie z ogól­ny­mi zasa­da­mi naci­skał peda­ły i mani­pu­lo­wał drąż­kiem zmia­ny bie­gów. Nie! Mam pra­wo i ocho­tą okre­ślić typ sil­ni­ka, żądać ABS i wie­le innych rze­czy. Jeżeli ja nie znam się aż tak na samo­cho­dach popro­szę o pomoc kogoś kto się zna. Jest ryzy­ko? Jest, ale to ja o nim decy­du­ję a nie sprze­daw­ca samochodów!

Jeden z wielu powodów takiego podejścia

Przytłaczająca więk­szość deve­lo­pe­rów, z któ­ry­mi się spo­tka­łem, roz­wią­zu­je pro­blem wydaj­no­ści np. pra­cy z listą pro­duk­tów, podej­mu­jąc kom­pro­mis pomię­dzy szcze­gó­ło­wo­ścią i wier­no­ścią opi­su pro­duk­tu” a wydaj­no­ścią (czas odpo­wie­dzi sys­te­mu) np. pod­czas pre­zen­ta­cji (gene­ro­wa­nia) uprosz­czo­ne­go cen­ni­ka. Większość zna­nych mi deve­lo­pe­rów nie­ste­ty pre­zen­tu­je coś co nazy­wam struk­tu­ral­ny model pro­jek­to­wa­nia opro­gra­mo­wa­nia opar­ty na ane­micz­nym mode­lu dzie­dzi­ny”. Z regu­ły roz­wią­zu­ją oni opi­sa­ny wyżej pro­blem cen­ni­ka, uprasz­cza­jąc opis pro­duk­tu (psu­ją model!), umiesz­cza­ją uprosz­czo­ne dane o pro­duk­cie w mode­lu rela­cyj­nym wraz z resz­tą danych i wal­czą z opty­ma­li­za­cją zapy­tań do tej rela­cyj­nej bazy (uprasz­cza­nie i denormalizacja).

Nie raz pro­wa­dzi to do sytu­acji, w któ­rej opro­gra­mo­wa­nie jest szyb­kie i nieprzydatne”. 

< – jeże­li nie jesteś ana­li­ty­kiem przejdź na koniec artykułu – >

Wygląda to wte­dy np. tak (źr. Fowler CQRS):

Od pra­wej: inter­fejs użyt­kow­ni­ka, model dzie­dzi­ny, baza danych (pod­sys­tem utrwalania).

CQRS

Nie od dzi­siaj zna­ny jest wzo­rzec pro­jek­to­wy, któ­ry radzi sobie z tym pro­ble­mem. Nazywa się CQRS, i tak jest opi­sy­wa­ny przez guru” ana­li­zy i pro­jek­to­wa­nia :), Martina Fowlera:

CQRS stands for Command Query Responsibility Segregation. It’s a pat­tern that I first heard descri­bed by Greg Young. At its heart is a sim­ple notion that you can use a dif­fe­rent model to upda­te infor­ma­tion than the model you use to read infor­ma­tion. This sim­ple notion leads to some pro­fo­und con­se­qu­en­ces for the design of infor­ma­tion sys­tems. (źr. CQRS).

Idea tego pomy­słu na tym, by nie opty­ma­li­zo­wać wydaj­no­ści sys­te­mu meto­dą, nie raz zgni­łe­go, kom­pro­mi­su, a podejść do pro­ble­mu dzie­ląc go na dwa pro­ble­my: zgod­ność mode­lu z rze­czy­wi­sto­ścią i wydaj­ność całe­go sys­te­mu. Pierwszy pro­blem roz­wią­zu­je­my two­rząc wier­ny model struk­tu­ry opi­su­ją­cej pro­duk­ty, dru­gi pro­blem – wydaj­no­ści – roz­wią­zu­je­my two­rząc dru­gi uprosz­czo­ny model pro­duk­tów, do celów szyb­kiej reali­za­cji kil­ku waż­nych zapy­tań” (np. publi­ka­cja on line uprosz­czo­nej posta­ci cennika).

Powyższy dia­gram poka­zu­je: UI (inter­fejs użyt­kow­ni­ka), poka­zu­je menu zgod­ne z opi­sem z przy­pad­ków uży­cia (wyma­ga­nia funk­cjo­nal­ne). Model dzie­dzi­ny (część środ­ko­wa) poka­zu­je ocze­ki­wa­ne roz­wią­za­nie (takie­go żądam w wyma­ga­niach). Polega ono wła­śnie na zapro­jek­to­wa­niu w czę­ści dzie­dzi­no­wej odręb­ne­go mode­lu do zarzą­dza­nia poje­dyn­czy­mi pro­duk­ta­mi i odręb­ne­go do wydaj­ne­go zarzą­dza­nia ich kolek­cją. Owszem, model się nie­co skom­pli­ko­wał (jest nie­co kosz­tow­niej­szy w imple­men­ta­cji), ale jako zama­wia­ją­cy mam to cze­go potrze­bu­ję: wydaj­ny i uży­tecz­ny system.

< – jeże­li nie jesteś ana­li­ty­kiem tu zacznij czy­tać dalej – >

Opisując wyma­ga­nia wyłącz­nie jako czar­ną skrzyn­kę” nie wiem co dosta­nę. Większość deve­lo­pe­rów będzie dąży­ło do uprosz­cze­nia imple­men­ta­cji (ich koszt, nie raz brak wie­dzy) by zaspo­ko­ić na mini­mal­nym pozio­mie wyma­ga­nia opi­sa­ne przy­pad­ka­mi uży­cia. Nie raz klient sły­szy tu musi­my to upro­ścić bo tak się nie da”, a zama­wia­ją­cy, nie mając kom­pe­ten­cji by pole­mi­zo­wać z taką opi­nią, zga­dza się i dostar­czo­ny w efek­cie sys­tem sta­je się zgni­łym kom­pro­mi­sem opar­tym wła­śnie na czar­nej skrzyn­ce” jako spe­cy­fi­ka­cji zamó­wień: dosta­li­śmy dokład­nie to co zamó­wi­li­śmy ale zupeł­nie nie to cze­go napraw­dę potrzebujemy”. 

Tak więc,

nie ma zna­cze­nia fakt, że na pew­no są na ryn­ku deve­lo­pe­rzy zna­ją­cy pro­blem, któ­ry opi­sa­łem i sto­su­ją­cy opi­sa­ne tu roz­wią­za­nie takich pro­ble­mów. Jednak nawet cień ryzy­ka (a jest ono na praw­dę duże), że dosta­nie­my bubla, daje zama­wia­ją­ce­mu pra­wo do szcze­gó­ło­we­go defi­nio­wa­nia wyma­gań jako bia­łej skrzyn­ki”, bo dzię­ki temu zama­wia­ją­cy dosta­nie to cze­go potrze­bu­je a nie tyl­ko to co zamó­wił”.

Dla zain­te­re­so­wa­nych tak­że do pobra­nia książ­ka z MSDN:

The CQRS pat­tern and event sour­cing are not mere sim­pli­stic solu­tions to the pro­blems asso­cia­ted with lar­ge-sca­le, distri­bu­ted sys­tems. By pro­vi­ding you with both a wor­king appli­ca­tion and writ­ten guidan­ce, we expect you’ll be well pre­pa­red to embark on your own CQRS jour­ney. (za CQRS Journey).

Inne artykuły na podobny temat

Komentarze

  1. Bartosz.jarmuz@gmail.com 17 maja 2018 at 12:00

    Cześć,
    Jak dla mnie, to zda­nie ?dosta­li­śmy dokład­nie to co zamó­wi­li­śmy ale zupeł­nie nie to cze­go napraw­dę potrze­bu­je­my? jest dokład­nym prze­ci­wień­stwem Twojej tezy, i świad­czy o tym, że funk­cjo­nal­ne wyma­ga­nia nie były na pierw­szym miej­scu… Zamawiający powi­nien spre­cy­zo­wać «co potrze­bu­je» i na koniec oce­nić czy to co otrzy­mał speł­nia jego wyma­ga­nia. To co opi­su­jesz, świad­czy o tym, że zama­wia­ją­cy okre­ślił «co i jak zbu­do­wać» a nie «co i jak ma działać».
    Kupując samo­chód nie inte­re­su­je Cię jak zbu­do­wa­na jest skrzy­nia DSG, tyl­ko mówisz że «chcę żeby bie­gi się popraw­nie same zmieniały» 🙂
    Swoją dro­gą, Fowler aku­rat dosyć kry­tycz­nie opi­su­je CQRS jako «źró­dło problemów/komplikacji w więk­szo­ści pro­jek­tów w któ­rych to widział», prawda?

    • Jaroslaw Zelinski 17 maja 2018 at 12:24

      Oddzielmy dwie rze­czy: spo­sób opi­sa­nia wyma­gań i to czym jest com­mand Separation (w tym CQRS). 

      Co do wyma­gań to przede wszyst­kim: wyma­ga­niem sto­la­rza jest: (1) rysu­nek tech­nicz­ny (lub szkic) młot­ka czy (2) opo­wie­ści sto­la­rza o potrze­bie przy­bi­ja­niu gwoź­dzi i wybi­ja­nia szyb? To zale­ży od podej­ścia, MDA/MDE nie uzna­je za wyma­ga­nia cze­goś co jest tego do cze­go i jak uży­je użyt­kow­nik. User sto­ry to nie wyma­ga­nia a co naj­wy­żej testy (wyma­ga­nia na dom dla deve­lo­pe­ra to pro­jekt archi­tek­to­nicz­ny a nie opis życia i zwy­cza­jów rodziny). 

      Co do CQRS, Fowler (i nie tyl­ko) opi­sał i ideę i czę­stą imple­men­ta­cję. Jeżeli mamy jeden sys­tem tablic rela­cyj­nych i do nich się odwo­łu­je­my na kil­ka spo­so­bów, to to nie jest CQRS (nie ma sepa­ra­cji tablic są to te same rela­cyj­ne tabli­ce). Separacja (w szcze­gól­no­ści obiek­to­wa) pole­ga na tym, że np. o tej samej czę­ści samo­cho­do­wej infor­ma­cje trzy­ma­my osob­no w agre­ga­tach zawie­ra­ją­cych szcze­gó­ły opi­su i osob­no obiek­tach pozwa­la­ją­cych szyb­ko zna­leźć wła­ści­wa część. Innymi sło­wy: maga­zy­nier ma pro­sty zeszy­cik do szyb­kie­go znaj­dy­wa­nia czę­ści na bazie nazwy, mar­ki samo­cho­du i rocz­ni­ka oraz sza­fę z osob­ny­mi książ­ka­mi opi­su­ją­cy­mi dokład­nie każ­dą z tych czę­ści. Całość sta­no­wi zestaw: i zeszy­cik i doku­men­ta­cja (książ­ki) na uni­kal­ny index każ­dej czę­ści, zeszy­cik słu­ży do szyb­kie­go iden­ty­fi­ko­wa­nia czę­ści a książ­ki do czer­pa­nia z nich deta­licz­nych opi­sów. Tam gdzie logi­ka (nawet napi­sa­na obiek­to­wo) pra­cu­je z jed­ną rela­cyj­ną bazą nie ma mowy o obiek­to­wo­ści, her­me­ty­za­cji itp… o CQRS też.. Bo zamiast sepa­ro­wa­nych dzie­dzi­no­wych repo­zy­to­riów masz jed­no: tę rela­cyj­ną, pozba­wio­ną redun­dan­cji, bazę danych.

  2. Jaroslaw Zelinski 17 maja 2018 at 12:39

    To co widzę jako przy­czy­nę pro­ble­mów wie­lu pro­jek­tów to teza Zamawiający powi­nien spre­cy­zo­wać ?co potrze­bu­je? i na koniec oce­nić czy to co otrzy­mał speł­nia jego wyma­ga­nia.” czy­ni z Zamawiającego pro­jek­tan­ta a ten nie ma kom­pe­ten­cji do tego: pie­karz pie­cze a nie kon­stru­uje pie­ce chle­bo­we… Pomiędzy pie­ka­rza a fabry­kę sprzę­tu AGD nale­ży wsta­wić pro­jek­tan­ta… Chyba, że zakła­da­my, że – podob­nie jak na ryn­ku nie­ru­cho­mo­ści – inwe­stor naj­pierw anga­żu­je archi­tek­ta a potem deve­lo­pe­ra.. wte­dy OK.

  3. Bartosz.jarmuz@gmail.com 17 maja 2018 at 14:08

    Przechodząc do ana­lo­gii budow­la­nych, klient mówi ile chce mieć pokoi i z któ­rej stro­ny taras, a nie dostar­cza rysun­ków tech­nicz­nych czy pro­jek­tu. W fir­mie budow­la­nej zaś, ktoś przy­go­to­wu­je na pod­sta­wie wyma­gań pro­jekt a maj­stro­wie na pod­sta­wie tego pro­jek­tu kła­dą cegły i rury itd. W opro­gra­mo­wa­niu też prze­cież jest archi­tekt któ­ry pro­jek­tu­je sys­tem i deve­lo­pe­rzy któ­rzy wpro­wa­dza­ją pro­jekt w życie, jed­ni front end, inni kanalizację:)
    Może to tyl­ko róż­ni­ce semantyczne.
    A co sądzisz o podej­ściu, w któ­rym sepa­ra­cję szcze­gó­łu od ogó­łu w ramach jed­nej bazy danych uzy­sku­je się za pomo­cą osob­ny tabel?
    Np, masz tabe­le Product, Maker, Function. Każda z nich ma roz­ma­ite szcze­gó­ły odno­śnie tych obiek­tów, ale masz też tabe­lę «ProductSummary», któ­ra zawie­ra tyl­ko ogól­ne FK, info o pro­duk­cie, nazwę twór­cy i nazwę funkcji?

    • Jaroslaw Zelinski 17 maja 2018 at 16:00

      Przechodząc do ana­lo­gii budow­la­nych, klient mówi ile chce mieć pokoi i z któ­rej stro­ny taras, a nie dostar­cza rysun­ków tech­nicz­nych czy projektu.”
      nie praw­da, w tej bran­ży musi… 

      Od lat nie sto­su­ję rela­cyj­ne­go mode­lu danych ;), ale osob­ne tabe­le są ok, poję­cie baza danych” to ser­wer RDBMS czy sys­tem powią­za­nych tabel? 😉

    • Bartosz.jarmuz@gmail.com 17 maja 2018 at 16:07

      Baza w rozu­mie­niu MS SQL Server, czy­li sys­tem powią­za­nych tabel + dodat­ko­we ele­men­ty typu pro­ce­du­ry, funk­cje, infra­struk­tu­ra «secu­ri­ty» itd. Wydaje mi się, że CQRS wraz z Event Sourcingiem są pew­nym prze­ro­stem for­my nad potrze­ba­mi w sys­te­mie któ­ry sobie two­rzę – chy­ba zde­cy­du­ję się na prost­sze podej­ście z repo­si­to­ry + unit of work. Czytałem też o podej­ściu w któ­rym two­rzy się jak­by osob­ne repo­si­to­ry servi­ce / pro­vi­der wła­śnie dla takie­go odchu­dzo­ne­go mode­lu «do raportów»…

    • Jaroslaw Zelinski 17 maja 2018 at 16:13

      Używanie obec­nie RDMS/SQL jako narzę­dzie two­rze­nia apli­ka­cji nie jest dobrym pomyłem.
      pro­po­nu­je lek­tu­rę Evansa Domain Driven Design, tak dzia­ła obec­nie więk­szość fra­me­wor­ków. Do rapor­tów są tabli­ce BI a nie bazy operacyjne 😉

    • Bartosz.jarmuz@gmail.com 17 maja 2018 at 16:26

      Dzięki, na pew­no spraw­dzę ten temat… Aczkolwiek może tro­chę póź­niej, mam nadzie­je że przy dobrze zapro­jek­to­wa­nej war­stwie inter­fej­sów infra­struk­tu­ry pod­mia­na war­stwy dostę­pu do danych nie będzie wyma­ga­ła dużych zmian;)

  4. chryplewiczpawel@wp.pl 15 stycznia 2019 at 12:58

    czy­taj przed publi­ka­cją. Tu są błę­dy orto­gra­ficz­ne i literówki.

  5. Radek Osak 1 kwietnia 2020 at 13:23

    Hej, Jeśli ktoś z Was szu­ka przy­kła­du apli­ka­cji napi­sa­nej z wyko­rzy­sta­niem CQRS to pole­cam ten artykuł 

    W tre­ści tego post’a może­cie zna­leźć link to całe­go pro­jek­tu na Github​.com

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.