Wzorzec analityczny Boundary Control Entity i ICONIX a także MVC i MVVM

Opisywałem ostat­nio wzo­rzec DDD jako narzę­dzie doku­men­to­wa­nia ana­li­zy i two­rze­nia mode­li ana­li­tycz­nych. Faktycznie, czy­tel­ni­cy mają wie­le racji twier­dząc, że czę­sto jest on zbyt bli­ski imple­men­ta­cji (zbyt szcze­gó­ło­wy a więc trud­ny dla nie­pro­gra­mi­stów). Niejednokrotnie lep­szym pomy­słem” jest opis logi­ki sys­te­mu na nie­co wyż­szym pozio­mie abs­trak­cji, pozo­sta­wia­jąc tym samym wię­cej swo­bo­dy developerowi.

Od cza­su do cza­su uży­wam wzor­ca BCE (Boundary, Control Entity) do mode­lo­wa­nia logi­ki biz­ne­so­wej. Jego rodo­wód się­ga chy­ba jesz­cze cza­sów począt­ków [[meto­dy­ki RUP]]. Pierwotnie był trak­to­wa­ny jako wzo­rzec ana­li­tycz­ny do mode­lo­wa­nia archi­tek­tu­ry kom­pa­ty­bil­nej z MVC, w swej ory­gi­nal­nej posta­ci nawią­zu­je do EJB/DAO ([[Enterprise JavaBeans/Data Access Object]]). Przykładowe stan­dar­do­we uży­cia (źr. wiki):

Wzorzec BCE koja­rzo­ny jest głów­nie z archi­tek­tu­rą EJB ([[Enterprise Java Beans]]). Od tam­tej pory EJB jed­nak nie­co ode­szło w nie­pa­mięć”, nie mamy już J2EE a JEE. Wzorzec MVC docze­kał się sen­sow­nej moim muta­cji do wer­sji [[MVVMC]], [[Model-View-ViewModel Contoler]], [[MVP]] (i kil­ku innych odmian). Diagram w tej kon­wen­cji jest tak­że nazy­wa­ny „[[robust­ness dia­gram]]” i koja­rzo­ny jest z meto­dy­ką ICONIX, jed­nak oso­bi­ście pole­cam sto­so­wa­nie zasad UML i uży­wa­nie dia­gra­mu klas zgod­nie z jego zasa­da­mi” czy­li uży­wa­nie związ­ków uży­cia (linia prze­ry­wa­na z gro­tem a nie cią­gła) i uzna­nie, że robust­ness dia­gram to po pro­stu dia­gram klas.

Podstawowa pier­wot­na wer­sja inter­pre­ta­cji wzor­ca BCE opi­sa­na jest zwięź­le tutaj:

This pat­tern is simi­lar to the Model View Controller pat­tern (descri­bed here [BUS96] and here [WIKP-MVC] among other pla­ces), but the Entity Control Boundary pat­tern is not sole­ly appro­pria­te for dealing with user inter­fa­ces and it gives the con­trol­ler a sli­gh­tly dif­fe­rent role to play. (za Entity-Control-Boundary Pattern).

Stosuję go jed­nak w nie­co zmie­nio­nej” formie.

Boundary, Control, Entity

Jak widać na powyż­szym, BCE nawią­zu­je bez­po­śred­nio do wzor­ca MVC, kla­sy boun­da­ry są w tej wer­sji już ele­men­ta­mi kom­po­nen­tu View. Starając się oddzie­lić (her­me­ty­zo­wać) logi­kę biz­ne­so­wą od czę­ści nie­biz­ne­so­wej” kodu, będą­cej w więk­szo­ści przy­pad­ków ele­men­ta­mi śro­do­wi­ska ([[fra­me­work]]) aplikacji.

Nieco inne podej­ście, to któ­re sto­su­ję obec­nie, opi­su­ję poni­żej. Zachowując pod­sta­wo­we zna­cze­nia tych trzech klas (BCE), nawią­za­łem do wzor­ca MVVM. Powstaje więc kon­struk­cja, w któ­rej Model ma struk­tu­rę M‑VM, pozo­sta­łe ele­men­ty View i Controler mają kon­kret­ne zadania:

  • M‑VM to struk­tu­ra czę­ści dzie­dzi­no­wej (Model-ViewModel),
  • View – tra­dy­cyj­nie odpo­wia­da za prezentację,
  • Controler – tra­dy­cyj­nie odpo­wia­da za zarzą­dza­nie cało­ścią, w tym poza-funk­cjo­nal­ne wyma­ga­nia (np. kodo­wa­nie trans­fe­ru danych nie jest ele­men­tem dzie­dzi­ny sys­te­mu, itp.)

Pewna cie­ka­wost­ką jest w tym wzor­cu wła­śnie ele­ment VM (ViewModel). Jego idea pole­ga na umiesz­cze­niu w obsza­rze dzie­dzi­ny dodat­ko­wej wie­dzy (logi­ki), ste­ru­ją­cej tym jakie (cho­dzi o ich bogac­two”) infor­ma­cje są poda­wa­ne na urzą­dze­nia pre­zen­tu­ją­ce o róż­nych moż­li­wo­ściach np. mały lub duży ekran, roz­dziel­czość czy wręcz komu­ni­ka­cja z pomo­cą SMS.

Powyższy dia­gram poka­zu­je sche­mat budo­wa­nia mode­lu na bazie tego wzor­ca. Jak widać ele­ment dzie­dzi­ny Model zacho­wu­je się zawsze tak samo, repre­zen­tu­je wie­dzę i logi­kę dzie­dzi­no­wą (np. kom­plet infor­ma­cji o oso­bie), Dziedzina (Model) jest dodat­ko­wo wypo­sa­żo­na w wie­dzę o moż­li­wo­ściach pre­zen­to­wa­nia peł­nej lub okro­jo­nej wer­sji wie­dzy publi­ko­wa­nej przez obiekt dzie­dzi­no­wy (kla­sy ViewModel). Dzięki temu View nie zawie­ra żad­nej logi­ki np. fil­tro­wa­nia peł­nej infor­ma­cji, dosta­je tyl­ko pro­sty przy­go­to­wa­ny zestaw danych do pre­zen­ta­cji poza samą pre­zen­ta­cją (dla uprosz­cze­nia pomię­to kom­po­nent Controller).

Jest to o tyle wygod­ne i waż­ne, że sto­so­wa­nie wzor­ca BCE wyłącz­nie do mode­lo­wa­nia logi­ki biz­ne­so­wej wyma­ga zacho­wa­nia her­me­ty­za­cji kom­po­nen­tu Model. Spotkać się moż­na z dia­gra­ma­mi, w któ­rych boun­da­ry będzie ele­men­tem kom­po­nen­tu Model (jako ViewModel). Jego rola to stwo­rze­nie dedy­ko­wa­ne­go inter­fej­su np. pomię­dzy kom­po­nen­tem View (lub Controller) a Model. Dzięki temu moż­li­we jest np. stwo­rze­nie odręb­ne­go inter­fej­su dla View na duży ekran i odręb­ne­go dla View na np. małych ekra­nach smart­fo­nów. Takie podej­ście wyglą­da tak:

Znaczenie (seman­ty­ka) stereotypów:

Boundary to kla­sa ozna­czo­na ste­reo­ty­pem «boun­da­ry», na dia­gra­mach repre­zen­to­wa­na może być iko­ną jak po lewej. Odpowiedzialność klas boun­da­ry to sepa­ra­cja mode­lu dzie­dzi­ny od innych kom­po­nen­tów (to czę­sto adap­ter, fasa­da, inter­fejs). Dzięki temu ewen­tu­al­ne zmia­ny Modelu nie prze­nio­są się na kom­po­nen­ty View i Controller oraz może­my zbu­do­wać np. róż­ne dedy­ko­wa­ne i bez­piecz­ne dzie­dzi­no­we adap­te­ry dostę­po­we do Modelu (np. w sys­te­mie nawi­ga­cyj­nym boun­da­ry dostar­czy Modelowi koor­dy­na­ty geo­gra­ficz­ne, View pozwo­li wpro­wa­dzić je z kla­wia­tu­ry a Controller z odbior­ni­ka – inter­fejs – GPS, Model sta­je nie­czu­ły na źró­dło tych koordynatów).

Control. Klasy ozna­czo­ne ste­reo­ty­pem «con­trol» lub iko­ną jak po lewej. Są to kla­sy odpo­wie­dzial­ne za wewnętrz­ne usłu­gi spe­cy­ficz­ne dla dzie­dzi­ny, umie­jęt­no­ści”. Nie są to kla­sy utrwa­la­ne. Ta kla­sa będzie obli­cza­ła np. czas prze­jaz­du na bazie wyty­czo­nej w sys­te­mie nawi­ga­cji strasy.

Entity. Najbardziej kon­tro­wer­syj­na kla­sa, w pier­wot­nej wer­sji inter­pre­ta­cji wzor­ca BCE (EJB) ozna­cza­ła tyl­ko dane utrwa­la­ne, nawią­zu­jąc do EJB sta­no­wi­ła mate­riał” na tak zwa­ny [[antyw­zo­rzec obiek­to­wy o nazwie ane­micz­ny model dzie­dzi­ny]]. Klas ozna­czo­nych ste­reo­ty­pem «enti­ty» uży­wa­my do mode­lo­wa­nia wie­dzy, czy­li zgro­ma­dzo­nych danych, nie są to jed­nak ane­micz­ne kla­sy bez ope­ra­cji. Będą to np. punk­ty na mapie cyfrowej.

Trzy powyż­sze typy klas są tu ele­men­ta­mi kom­po­nen­tu Model. Syntaktyka odwo­łań ele­men­tów wzor­ca BCE:

Obrazowo wyglą­da to tak:

Przejście na poziom DDD, dro­gę w kie­run­ku imple­men­ta­cji tego mode­lu przy powyż­szych zało­że­niach, moż­na reali­zo­wać np. tak:

Interpretacja ta pozwa­la zacho­wać głów­ny cel czy­li roz­ło­że­nie logi­ki Modelu na pro­stą” mapę trzech ele­men­tów: kon­tak­tu z oto­cze­niem (boun­da­ry), reali­za­cji logi­ki i reguł (con­trol) oraz zacho­wy­wa­nia bier­nych” obiek­tów biz­ne­so­wych (enti­ty). Mała adap­ta­cja kon­wen­cji do wzor­ca MVVM-V‑C pozwa­la uzy­skać kom­fort cał­ko­wi­tej sepa­ra­cji tak mode­lo­wa­ne­go Modelu od jego otoczenia.

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­nia funk­cjo­nal­ne i poza-funk­cjo­nal­ne. 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 autor­skie pra­wo oso­bi­ste do pro­jek­tu tej reali­za­cji (mająt­ko­we­go nie musi wydać).

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 ryzykami. 

Literatura

Polecam cie­ka­wy arty­kuł na podob­ny temat:

As we have seen, the fun­da­men­tal idea of MVC is a sepa­ra­tion of the doma­in logic and the GUI objects into the Model and the View. These two are lin­ked indi­rec­tly by using the Publish-Subscribe mecha­nism known as the Observer pat­tern. Another ele­ment of this design is a Controller that imple­ments a par­ti­cu­lar stra­te­gy for the View. (Model View Controller, Model View Presenter, and Model View ViewModel Design Patterns – CodeProject).

Oraz (apro­po MVVM iMVC):

Warto pisać apli­ka­cje w taki spo­sób, żeby moż­na było je w cało­ści obsłu­gi­wać za pomo­cą testów jed­nost­ko­wych. Jak nale­ży to rozu­mieć? Budując apli­ka­cję w taki spo­sób, że cała jej funk­cjo­nal­ność dostęp­na jest bez inter­fej­su użyt­kow­ni­ka, możesz każ­dy jej aspekt opi­sać za pomo­cą testów jed­nost­ko­wych. To pozwa­la na wstęp­ne testo­wa­nie zgod­no­ści apli­ka­cji z wyma­ga­nia­mi wstęp­ne, bo cały czas nale­ży pamię­tać, że testy jed­nost­ko­we to narzę­dzie, wspie­ra­ją­ce pro­gra­mi­stów, a nie teste­rów i jako takie nie może zastą­pić testów apli­ka­cji. (Wykorzystanie TDD wraz ze wzor­cem MVVM).

Kiedy i po co robimy te modele?

Tu nawią­żę do MDA (tu co nie­co o Model Driven Architecture). W łań­cu­chu mode­li MDA mamy trzy mode­le: CIM->PIM->PSM. Analiza biz­ne­so­wa na pierw­szym eta­pie to two­rze­nie mode­lu orga­ni­za­cji pomi­ja­ją­ce­go ist­nie­nie jakie­go­kol­wiek opro­gra­mo­wa­na (CIM – [[Computation Independent Model]]), celem jest peł­ne zro­zu­mie­nie i opi­sa­nie funk­cjo­no­wa­nia organizacji.

Kolejny etap to opra­co­wa­nie mode­lu dzie­dzi­ny pro­jek­to­wa­ne­go (wyma­ga­ne­go) opro­gra­mo­wa­nia. To model PIM ([[Platform Independent Model]]). Jego celem jest udo­ku­men­to­wa­nie logi­ki opro­gra­mo­wa­nia, wyma­ga­nia poza funk­cjo­nal­ne są reali­zo­wa­ne nie­za­leż­nie od tej logi­ki. Tak więc model PIM do coś co nazy­wa­ne bywa: wyma­ga­nia dzie­dzi­no­we”. Wymagania funk­cjo­nal­ne nie opi­su­ją w ogó­le logi­ki biz­ne­so­wej, same przy­pad­ki uży­cia nie są wystar­cza­ją­ce do napi­sa­nia opro­gra­mo­wa­nia, potrzeb­na jest wie­dza o logi­ce biz­ne­so­wej. Funkcjonalność sys­tem sprze­da­ży auto­ma­tycz­nie uwzględ­nia upu­sty dla klien­tów” nic nie mówi. Ale gdzie defi­ni­cja logi­ki udzie­la­nia tych upu­stów? Gdzie jest wie­dza o upu­stach a gdzie o towa­rach? Przy klien­cie czy przy towa­rze? Nie wia­do­mo, trze­ba to jakoś zro­zu­mieć i udo­ku­men­to­wać, w spo­sób pozwa­la­ją­cy na imple­men­ta­cją czy­li jed­no­znacz­nie. I po to się two­rzy mode­le PIM.

Tu jed­nak nale­ży się mała uwa­ga (bo nigdy nie mów nigdy): bywa, że ogra­ni­cze­nie o tre­ści mak­sy­mal­ny czas ocze­ki­wa­nia na ofer­tę nie może prze­kro­czyć pro­gu cier­pli­wo­ści 80% klien­tów”. Pozostaje zba­da­nie pro­gu cier­pli­wo­ści”, ten para­metr nie jest ele­men­tem regu­ły biz­ne­so­wej gdyż jest wła­śnie para­me­trem” a nie zasa­dą” (regu­ły biz­ne­so­we to zasa­dy postę­po­wa­nia a nie regu­ły podej­mo­wa­nia decy­zji czy mier­ni­ki). Ta regu­ła może stać się ele­men­tem dzie­dzi­ny pro­jek­to­wa­ne­go sys­te­mu jeże­li np. jej speł­nie­nie jest ele­men­tem budo­wy prze­wa­gi ryn­ko­wej. Co to zna­czy? Że nie nale­ży opty­ma­li­zo­wać obec­ne­go mode­lu dzie­dzi­ny (np. pod­no­sze­nie wydaj­no­ści poprzez uprosz­cze­nie struk­tu­ry opi­su pro­duk­tów) a dodać do dzie­dzi­ny struk­tu­rę pozwa­la­ją­cą na wyko­ny­wa­nie pew­nych wybra­nych czyn­no­ści pro­ściej i szyb­ciej. To jed­nak temat o wzor­cu pro­jek­to­wym CQRS ale to temat na inny arty­kuł.

(inne źró­dła:

basic rules apply: Actors can only talk to boun­da­ry objects.Figure 3. Robustness Analysis RulesBoth boun­da­ry objects and enti­ty objects are nouns, and con­trol­lers are verbs. Nouns can’t talk to other nouns, but verbs can talk to either nouns or verbs. Boundary objects can only talk to con­trol­lers and actors. Entity objects can only talk to con­trol­lers. Controllers can talk to boun­da­ry objects and enti­ty objects, and to other con­trol­lers, but not to actors

źr. Memorandum).

Inne artykuły na podobny temat

Komentarze

  1. Sławek Ryszkowski 21 października 2012 at 00:06

    Omówiony wzo­rzec BCE jest bar­dzo podob­ny do tego, któ­ry wyko­rzy­sty­wa­ny jest w meto­dzie ICONIX, któ­ra to rów­nież daje wytycz­ne jak sepa­ro­wać logi­kę biz­ne­so­wą – tu rów­nież meto­da pozwa­la zacho­wać wyż­szy sto­pień abs­trak­cji niż DDD. Niemniej jed­nak zasto­so­wa­nie DDD umoż­li­wia dokład­ne odzwier­cie­dle­nie logi­ki biznesowej.

    • Jarek Żeliński 22 października 2012 at 00:55

      To praw­da, w ICONIX mamy tu jed­nak nie­stan­dar­do­wy dia­gram: Robustness Diagram (trud­no go ryso­wać i prze­ka­zy­wać dalej, narzę­dzia CASE z regu­ły nie wspie­ra­ją go), jest to jed­nak chy­ba po pro­tu dia­gram klas i opi­sa­ne ste­reo­ty­py… Inna spra­wa, że ICONIC narzu­ca poprze­dza­nie kodo­wa­nia projektowaniem 🙂 

      Kompromis pomię­dzy BCE a DDD chy­ba zawsze powi­nien być kom­pro­mi­sem pomię­dzy ryzy­kiem zbyt­nie­go uogól­nie­nia” a ocze­ki­wa­niem wykonawcy ;).

    • Jarek Żeliński 22 października 2012 at 21:25

      Pogrzebałem w ICONIX, jest dużo wspól­ne­go… nawet zmo­dy­fi­ko­wa­łem artykuł…

  2. Sławek Ryszkowski 22 października 2012 at 09:28

    Czy trud­no ryso­wać dia­gram Robustness? Myślę że nie łatwo, podob­nie zresz­tą jak i model dzie­dzi­no­wy w meto­dzie DDD. Zastosowanie tej meto­dy, podob­nie jak wzor­ca ECB, widzę raczej jako etap pośred­ni przy pro­jek­to­wa­niu mode­lu dzie­dzi­no­we­go zgod­ne­go ze wzor­ca­mi DDD. Pytanie czy war­to taki etap wyko­ny­wać? Czy wyko­na­nie dodat­ko­we­go mode­lu nie wpro­wa­dzi w tym przy­pad­ku wię­cej zamie­sza­nia niż pożytku?

    • Jarek Żeliński 22 października 2012 at 09:36

      Oba dia­gra­my to głę­bo­ka ana­li­za i pro­jek­to­wa­nie, to nie może być łatwe :). Osobiście wyda­je mi się, że trzy kloc­ki BCE na dia­gra­mie klas to wła­śnie Robustness Diagram (z doku­men­ta­cji tych wzor­ców i meto­dy­ki na to wycho­dzi, BCE to ste­reo­ty­py klas, a Robustness dia­gram to ich uży­cie). Co do nad­mia­ro­wo­ści, to skła­niam się ku tezie, że przej­ście: ana­li­za poję­cio­wa, model BCE (Robustness), model DDD i potem pro­jekt imple­men­ta­cji, to natu­ral­na dro­ga ana­li­zy i pro­jek­to­wa­nia zstę­pu­ją­ce­go (od ogó­łu do szcze­gó­łu). Np. w pierw­szej ite­ra­cji pla­nu­je­my uży­cie usłu­gi (con­trol) o nazwie two­rze­nie nowe­go doku­men­tu”, w dru­giej ite­ra­cji, po akcep­ta­cji kon­cep­cji, decy­du­je­my któ­re­go wzor­ca kre­acyj­ne­go uży­je­my w miej­scy Tworzenie nowych doku­men­tów”, moim zda­niem to podob­nie jak dekom­po­zy­cja procesów…

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.