Zwinne projektowanie interfejsu użytkownika

W ostat­nim arty­ku­le zwra­ca­łem uwa­gę mię­dzy inny­mi na bar­dzo waż­ny ele­ment ana­li­zy i pro­jek­to­wa­nia jakim jest abs­tra­ho­wa­nie od deta­li, ponieważ: 

…ana­li­tyk musi abs­tra­ho­wać od wszel­kich deta­li, bez tego pro­jekt zosta­nie już na samym począt­ku ?zabi­ty? ich ilo­ścią. [1]

Nieco wcze­śniej (2013 r.) pisa­łem o tym, kie­dy uzgad­niać deta­le, któ­re i gdzie one są: 

Cała logi­ka biz­ne­so­wa jest wyko­ny­wa­na wewnątrz apli­ka­cji (infor­ma­cje o ewen­tu­al­nych błę­dach poja­wią się po zatwier­dze­niu for­mu­la­rza), np. upust może być spraw­dzo­ny (albo nali­czo­ny) dopie­ro po skom­ple­to­wa­niu danych wyma­ga­nych do jego wyli­cze­nia, czy­li będzie to kil­ka róż­nych pól (naj­mniej dwa :)). Bywa, że do wyli­cze­nia cze­goś potrzeb­ne będą dane nie wpro­wa­dza­ne do danej for­mat­ki fak­tu­ry, np. sal­do klien­ta. [2]

Tym razem kil­ka słów o tym jak skom­pli­ko­wać i zabić pro­jekt już pierw­sze­go dnia. Jednym z naj­bar­dziej ryzy­kow­nych spo­so­bów roz­po­czy­na­nia pro­jek­tu jest roz­po­czy­na­nie od kon­sul­ta­cji z użyt­kow­ni­kiem w kwe­stii inter­fej­su użyt­kow­ni­ka. Prowadzi to do sytu­acji, w któ­rej jesz­cze nie mamy żad­ne­go poję­cia o logi­ce biz­ne­so­wej i archi­tek­tu­rze apli­ka­cji, a już dekla­ru­je­my to jak będzie się ona komu­ni­ko­wa­ła z użyt­kow­ni­kiem (cie­ka­we na jakiej podstawie?). 

Do napi­sa­nia tego arty­ku­łu skło­nił mnie ten wpis:

The role of design still puz­zles many agi­le teams I work with. When sho­uld the design acti­vi­ties take pla­ce? Who sho­uld car­ry them out? How are design deci­sions best cap­tu­red? This blog tries to answer the questions by discus­sing a user-cen­tric, ite­ra­ti­ve, and col­la­bo­ra­ti­ve design pro­cess for Scrum and Kanban teams. [3]

Autor poka­zu­je jak wal­czy” ze zło­żo­no­ścią na tym eta­pie, ja pra­gnę zasu­ge­ro­wać by do tej zło­żo­no­ści na tym eta­pie po pro­stu nie dopusz­czać. Powyższy dia­gram poka­zu­je z czym wal­czy ana­li­tyk, któ­ry dopro­wa­dzi do zebra­nia wyrwa­nych z kon­tek­stu (tak, nie ma mode­lu logi­ki więc dys­ku­sje o GUI są ode­rwa­ne od kon­tek­stu) wyma­gań” (histo­ryj­ki użyt­kow­ni­ka, lewa kolum­na tabli­cy Story Area), któ­rych zama­wia­ją­cy może naopo­wia­dać” bar­dzo dużo.

A jak ina­czej? Pomoże nam sto­so­wa­nie wzor­ców archi­tek­to­nicz­nych. Są one od lat dostęp­ne w więk­szo­ści fra­me­wor­ków (szko­da, że bar­dzo czę­sto deve­lo­pe­rzy je igno­ru­ją). Poniżej pro­sty, abs­trak­cyj­ny model kla­sycz­ne­go wzor­ca MVC.

W archi­tek­tu­rze wydzie­la się kom­po­nen­ty (sepa­ro­wa­nie odpo­wie­dzial­no­ści): odpo­wie­dzial­ny za obsłu­gę dia­lo­gu z użyt­kow­ni­kiem (View), odpo­wie­dzial­ny za tech­no­lo­gie, jakość, bez­pie­czeń­stwo, ste­ro­wa­nie itp. (Controler) oraz odpo­wie­dzial­ny za (całą a nie tyl­ko dane!) logi­kę biz­ne­so­wą (Model). 

Zarządzanie zło­żo­no­ścią pole­ga tu na tym, by na począt­ku ana­li­zy i pro­jek­to­wa­nia abs­tra­ho­wać cał­ko­wi­cie od deta­li GUI! (a dokład­nie od całej tech­no­lo­gii czy­li ele­men­tów View i Contoler). Kluczową odpo­wie­dzial­no­ścią apli­ka­cji jest reali­za­cja okre­ślo­nej logi­ki biz­ne­so­wej. Na tym eta­pie powi­nien powstać model przy­pad­ków uży­cia rozu­mia­ny jako pro­sty dia­log pomię­dzy użyt­kow­ni­kiem a apli­ka­cją, tu celem jest uchwy­ce­nie klu­czo­wych wyma­gań jaki­mi są wyma­ga­ne usłu­gi apli­ka­cyj­ne reali­zo­wa­ne przez apli­ka­cję oraz opra­co­wa­nie wewnętrz­nej archi­tek­tu­ry – Modelu, któ­ra te usłu­gi zre­ali­zu­je. Dopiero po prze­te­sto­wa­niu całej logi­ki biz­ne­so­wej na mode­lach, war­to się zabie­rać na kom­pli­ko­wa­nie pro­jek­tu poprzez opra­co­wa­nie deta­li GUI, ste­ro­wa­nia, bez­pie­czeń­stwa itp.. Postępowanie takie umoż­li­wia wzo­rzec archi­tek­to­nicz­ny MVVM opra­co­wa­ny ponad 10 lat temu. Wzorzec ten wpro­wa­dza dodat­ko­wy kom­po­nent pomię­dzy kom­po­nen­ty View i Model: View-Model, któ­ry reali­zu­je logi­kę dia­lo­gu GUI-użyt­kow­nik. Dzięki temu może­my wydzie­lić etap pra­cy nad GUI, jako osob­ny w pro­jek­cie, któ­ry zre­ali­zu­je (póź­niej) tak zwa­ny UX desi­gner”, a deve­lo­per zamie­ni pier­wot­nie abs­trak­cyj­ny kom­po­nent View na imple­men­ta­cje View-View Model”.

Bardzo dobry opis tego podejścia:

W przy­pad­ku war­stwy pre­zen­ta­cji moż­na wyko­rzy­stać m. in. nastę­pu­ją­ce roz­wią­za­nia: MVC, MVP czy Model-View-ViewModel. Ze wzglę­du na mecha­nizm wią­zań (bin­ding), pro­gra­mi­stom WPF oraz Silverlight, pole­ca­ny jest wzo­rzec MVVM ? jest to tech­no­lo­gia umoż­li­wia­ją­ca bar­dzo łatwą imple­men­ta­cję wzor­ca. […] …po co utrud­niać sobie zada­nie poprzez wyko­rzy­sty­wa­nie MVVM, zamiast pisać apli­ka­cję w kla­sycz­ny spo­sób (za pomo­cą code-behind)? W koń­cu wdro­że­nie prak­tycz­nie każ­de­go wzor­ca pro­jek­to­we­go wyma­ga tro­chę więk­szych począt­ko­wych nakła­dów pra­cy.

Podejście Code-Behind (auto­no­mo­us view ? AV) ma poważ­ną wadę ? nie gwa­ran­tu­je ela­stycz­no­ści oraz testo­wal­no­ści. Podsumowując, wpro­wa­dze­nie wzor­ca [MVVM, przy­pis auto­ra] umożliwia:

  • nie­za­leż­ność logi­ki od spo­so­bu wyświe­tla­nia danych,
  • nie­za­leż­ność kodu od tech­no­lo­gii, w któ­rej wyko­na­na jest war­stwa prezentacji,
  • wyko­ny­wa­nie testów ? za pomo­cą MVVM czy MVP moż­li­we jest wyko­na­nie testów zauto­ma­ty­zo­wa­nych (np. jednostkowych),
  • łatwą zamia­nę wido­ków (brak sztyw­nych powią­zań mię­dzy wido­kiem a logi­ką). [4]

(Tak: sto­so­wa­nie wzor­ców pod­no­si począt­ko­wą pra­co­chłon­ność ale zwra­ca się z nawiąz­ką w dal­szych cyklach życia pro­jek­tu.) Strukturę i histo­rię powsta­nia tej archi­tek­tu­ry zain­te­re­so­wa­ni mogą poznać tak­że tu: 

Model View View Model (MVVM) 
In 2005, John Gossman, Architect at Microsoft, unve­iled the Model-View-ViewModel (MVVM) pat­tern on his blog. MVVM is iden­ti­cal to Fowler?s Presentation Model, in that both pat­terns featu­re an abs­trac­tion of a View, which con­ta­ins a View?s sta­te and beha­vior. Fowler intro­du­ced Presentation Model as a means of cre­ating a UI plat­form-inde­pen­dent abs­trac­tion of a View, whe­re­as Gossman intro­du­ced MVVM as a stan­dar­di­zed way to leve­ra­ge core featu­res of WPF and Silverlight to sim­pli­fy the cre­ation of user inter­fa­ces. MVVM is a spe­cia­li­za­tion of the more gene­ral PM pat­tern, tailor-made for the WPF and Silverlight plat­forms to leve­ra­ge core featu­res of WPF such as data bin­ding, com­mands , templates.

This dia­gram take from MSDN depicts MVVM Pattern in action.

image[5]

Tak więc ana­li­zę i pro­jek­to­wa­nie war­to zacząć od logi­ki i szkie­le­tu archi­tek­tu­ry, a ta to przede wszyst­kim Model (dzie­dzi­ny) sys­te­mu czy­li kom­plet­na logi­ka biz­ne­so­wa (utoż­sa­mia­nie mode­lu dzie­dzi­ny z rela­cyj­ną bazą danych to poważ­ny błąd i nie­po­ro­zu­mie­nie). Po upo­ra­niu się z tym eta­pem pro­jek­tu ma sens opra­co­wy­wa­nie deta­li komu­ni­ka­cji z użyt­kow­ni­kiem, bo dopie­ro teraz zna­my wyma­ga­nia i ogra­ni­cze­nia logi­ki biz­ne­so­wej. Odkrywanie ich dopie­ro na eta­pie pro­to­ty­po­wa­nia to sta­now­czo za póź­no, bo gene­ru­je to ogrom­ne kosz­ty cyklicz­ne­go refak­to­rin­gu kodu (albo kod szyb­ko sta­je się bry­łą błota”). 

Bardzo czę­sto sły­szę, że klient chce jak naj­szyb­ciej coś zoba­czyć. Rzecz w tym, że jeże­li się na to zgo­dzi­my, powsta­je i jest akcep­to­wa­na masa tak zwa­nych poboż­nych życzeń”, a klient bar­dzo szyb­ko się przy­wią­zu­je do tego co zoba­czył na pre­zen­ta­cji (i nie chce odpu­ścić). W efek­cie two­rzy się spi­ra­la żądań, testów i popra­wek, któ­re szyb­ko prze­kształ­ca­ją agi­le” w poraż­kę budże­tu i har­mo­no­gra­mu. Praktyka poka­zu­je, że budżet zawsze ma limit, dla­te­go bar­dzo wie­le takich pro­jek­tów koń­czy albo w koszu na śmie­ci albo efek­ty sta­no­wią tyl­ko namiast­kę tego co opi­sy­wa­ła pier­wot­na wizja. Jeżeli zaś zacznie­my od jądra sys­te­mu a na koniec zosta­wi­my sobie maki­jaż” jakim jest GUI, szan­sa na suk­ces będzie znacz­nie więk­sza. Problem pole­ga na tym, że moda na user-cen­tric, ite­ra­ti­ve, and col­la­bo­ra­ti­ve design” jest sil­na mimo tego, że jest przy­czy­ną wie­lu porażek. 

Tak więc odpo­wiedź na pyta­nie jak pora­dzić sobie z życze­nia­mi biz­ne­su, brzmi: nie dopusz­czać do ich wyar­ty­ku­ło­wa­nia :). Projektowanie i two­rze­nie samo­cho­du roz­po­czy­na się od pod­wo­zia i napę­du a nie od deski rozdzielczej…

Bibliografia

[1]
J. Zelinski, ?Model czy abs­trak­cja?, Jarosław Żeliński IT-Consulting, 22-wrz-2017. [Online]. Available: https://it-consulting.pl//2017/09/22/model-czy-abstrakcja/. [Udostępniono: 25-wrz-2017]
[2]
J. Zelinski, ?Gdzie są te cho­ler­ne szcze­gó­ły?, Jarosław Żeliński IT-Consulting, 18-cze-2014. [Online]. Available: https://it-consulting.pl//2014/06/18/gdzie-sa-te-cholerne-szczegoly/. [Udostępniono: 25-wrz-2017]

Panowanie nad złożonością czyli gdzie są Przypadki Użycia czyli MVVM-MVC

Niedawno w arty­ku­le o dość wyzy­wa­ją­cym tytu­le 😉 Gdzie są te cho­ler­ne szcze­gó­ły pisa­łem o zło­żo­no­ści wyma­gań i tym, gdzie ta zło­żo­ność jest (mogła by być, powin­na być doku­men­to­wa­na, jak kto woli). Tam sku­pi­łem się na takich szcze­gó­łach jak regu­ły biz­ne­so­we i zło­żo­ne typy danych, czy­li tym co potocz­nie (i nie do koń­ca słusz­nie) nazy­wa się wali­da­cja­mi” ([[wali­da­cja]]).

Drugim ele­men­tem nio­są­cym” szcze­gó­ły jest dia­log użyt­kow­ni­ka z apli­ka­cją czy­li ekra­ny”. Tu poja­wia się kolej­na por­cja wyma­gań, nie raz bar­dzo szcze­gó­ło­wych, zaciem­nia­ją­cych nie raz głów­ny sens two­rze­nia dane­go opro­gra­mo­wa­nia: sce­na­riu­sze pra­cy z ekra­nem (for­mat­ką ekra­no­wą itp.).

Jak już nie raz pisa­łem, ogól­na zasa­dą (dobrą prak­ty­ką) w inży­nie­rii jest abs­tra­ho­wa­nie oraz zarzą­dza­nie pozio­mem szcze­gó­ło­wo­ści każ­de­go eta­pu pra­cy na pro­jek­tem. Operowanie poję­cia­mi (ter­mi­na­mi) zamiast ich defi­ni­cja­mi, to abs­tra­ho­wa­nie od szcze­gó­łów czy­li ich her­me­ty­za­cja, np. Kontrahent” to nazwa pod­mio­tu, jego NIP, adres”.

Wymagania wobec apli­ka­cji zwią­za­ne z inte­rak­cją aktor-sys­tem, ich defi­nio­wa­nie i pro­jek­to­wa­nie reali­za­cji, nie nale­żą do łatwych eta­pów ana­li­zy i pro­jek­tu, są nie raz bar­dzo szcze­gó­ło­we. To powód dla któ­re­go war­to je tak­że her­me­ty­zo­wać”. Jak? Pomagają w tym dwie rze­czy: wyod­ręb­nie­nie pro­jek­to­wa­nia (doku­men­to­wa­nia) szcze­gó­łów inte­rak­cji jako etap pro­jek­to­wa­nia nazy­wa­ny [[User Experience]] (dalej UX) oraz uży­cie wzor­ca pro­jek­to­we­go MVVM-MVC.

Najpierw jed­nak wzor­ce, bo te dadzą nam kon­tekst i gra­ni­ce her­me­ty­za­cji. Wzorzec MVVM i korzy­ści pły­ną­ce z jego uży­cia, przy­stęp­nie opi­sa­no na stro­nie MSDN:

Przed omó­wie­niem wzor­ca, war­to zasta­no­wić się, po co utrud­niać sobie zada­nie poprzez wyko­rzy­sty­wa­nie MVVM, zamiast pisać apli­ka­cję w kla­sycz­ny spo­sób (za pomo­cą code-behind)? W koń­cu wdro­że­nie prak­tycz­nie każ­de­go wzor­ca pro­jek­to­we­go wyma­ga tro­chę więk­szych począt­ko­wych nakła­dów pracy.

Podejście Code-Behind (auto­no­mo­us view ? AV) ma poważ­ną wadę ? nie gwa­ran­tu­je ela­stycz­no­ści oraz testo­wal­no­ści. Podsumowując, wpro­wa­dze­nie wzor­ca umożliwia:

  1. nie­za­leż­ność logi­ki od spo­so­bu wyświe­tla­nia danych,
  2. nie­za­leż­ność kodu od tech­no­lo­gii, w któ­rej wyko­na­na jest war­stwa prezentacji,
  3. wyko­ny­wa­nie testów ? za pomo­cą MVVM czy MVP moż­li­we jest wyko­na­nie testów zauto­ma­ty­zo­wa­nych (np. jednostkowych),
  4. łatwą zamia­nę wido­ków (brak sztyw­nych powią­zań mię­dzy wido­kiem a logiką).

(Wprowadzenie do wzor­ca pro­jek­to­we­go Model-View-ViewModel na przy­kła­dzie apli­ka­cji WPF | MSDN (Polska).)

Z per­spek­ty­wy ana­li­zy i pro­jek­to­wa­nia ([[OOAD]]) naj­istot­niej­sze są pierw­sze dwa punk­ty, bo umoż­li­wia­ją her­me­ty­za­cję (oddzie­le­nie) logi­ki biz­ne­so­wej i pro­jek­tu opi­su­ją­ce­go inte­rak­cje aktor-sys­tem czy­li UX. Punkt czwar­ty daje speł­nie­nie jed­nej z zasad SOLID czy­li łatwość roz­sze­rze­nia bez potrze­by mody­fi­ka­cji”. Ta ostat­nia cecha to np. doda­wa­nie nowych inter­fej­sów użyt­kow­ni­ka do kolej­nych nowych urzą­dzeń (smart­fon, tablet, dedy­ko­wa­ne urzą­dze­nia i wyświe­tla­cze), bez potrze­by inge­ro­wa­nia w kod obsłu­gu­ją­cy już opro­gra­mo­wa­ne urządzenia.

Jak to wyglą­da z per­spek­ty­wy archi­tek­tu­ry apli­ka­cji i jej pro­jek­tan­ta? Poniżej model:

MVVM i MVC

Co tu mamy? Mamy MVVM i MVC na jed­nym dia­gra­mie. MVVM pole­ga na wsta­wie­niu pomię­dzy widok (View) a Model dodat­ko­we kom­po­nen­tu, któ­ry sta­no­wi wer­sję logi­ki biz­ne­so­wej zawie­ra­ją­cą ogra­ni­cze­nia wyświe­tla­cza” i dedy­ko­wa­ne (spe­cy­fiacz­ne) tyl­ko dla nie­go zacho­wa­nia (to tak­że pozwa­la uni­ka­nia bar­dzo złej prak­ty­ki jaką jest umiesz­cza­nie logi­ki biz­ne­so­wej w kom­po­nen­cie View). Innymi sło­wy, jeże­li jakieś zacho­wa­nia sys­te­mu są spe­cy­ficz­ne dla kon­kret­ne­go typu wyświe­tla­cza (ale może to być spe­cy­fi­ka akto­ra o czym dalej), logi­kę tę her­me­ty­zu­je­my w kom­po­nen­cie ViewModel.

Mając taką abs­trak­cję apli­ka­cji jak powy­żej, łatwo będzie osob­no opi­sać ją przy­pad­ka­mi uży­cia, uzna­jąc je za usłu­gi sys­te­mu (te świad­czy kom­po­nent Model) oraz osob­no szcze­gó­ło­wy­mi sce­na­riu­sza­mi UX zamknię­ty­mi w parze kom­po­nen­tów View-ViewModel. Oba te ele­men­ty pro­jek­tu – UX i Use Case, są więc ład­nie” odse­pa­ro­wa­ne, nie wpły­wa­ją na sie­bie nawza­jem i pozwa­la­ją na łatwą roz­bu­do­wę całe­go sys­te­mu, nie­wy­ma­ga­ją­cą mody­fi­ko­wa­nia już powsta­łe­go kodu (i dokumentacji).

Nawiąże jesz­cze do spe­cy­fi­ki akto­ra”. Bardzo czę­sto w sys­te­mach inter­ne­to­wych, mamy potrze­bę sepa­ra­cji użyt­kow­ni­ków z poza fir­my” (np. klien­ci skle­pu inter­ne­to­we­go, inter­fej­sy samo­ob­słu­gi dla klien­tów ser­wi­su itp.). Wiąże się to nie raz z bar­dzo zło­żo­ny­mi zasa­da­mi kon­tro­li dostę­pu do ele­men­tów mode­lu 9czyli dość głę­bo­ko w sys­te­mie). Potrafi to bar­dzo skom­pli­ko­wać cały pro­jekt kom­po­nen­tu Model, a nie raz potrze­by jego istot­nej prze­bu­do­wy. Można tego unik­nąć, her­me­ty­zu­jąc ten obszar. Bardzo czę­sto oso­ba (użyt­kow­nik, aktor sys­te­mu) z zewnątrz ma bar­dzo ogra­ni­czo­ne moż­li­wo­ści korzy­sta­nia z logi­ki całe­go sys­te­mu. Łatwiej jest zapro­jek­to­wać dedy­ko­wa­ny, rela­tyw­nie pro­sty kom­po­nent ViewModel i połą­czyć go z Modelem, niż mody­fi­ko­wać Model Dziedziny sys­te­mu by obsłu­gi­wał, nowe, nie raz bar­dzo wyra­fi­no­wa­ne, ogra­ni­cze­nia dostępu.

Tak więc przy­pad­ka­mi uży­cia opi­su­je­my abs­trak­cję jaką jest [[Model Dziedziny Systemu]]. Są one wte­dy pro­ste, zawie­ra­ją sce­na­riusz, któ­ry w skró­cie ma postać: aktor ini­cju­je usłu­gę, sys­tem pre­zen­tu­je for­mu­larz do wypeł­nie­nia, aktor wypeł­nia go i potwier­dza, sys­tem potwier­dza ode­bra­nie danych i poka­zu­je wynik swo­jej pra­cy (lub komu­ni­ka­ty o błę­dach). Tu sku­pia­my się na opi­sie tego jakie usłu­gi są wyma­ga­ne od sys­te­mu. Kolejny etap to kom­pli­ko­wa­nie” każ­de­go sce­na­riu­sza w posta­ci pro­jek­to­wa­nia, dla każ­de­go przy­pad­ku uży­cia, któ­ry tego wyma­ga, róż­ne­go rodza­ju wizar­dów lub wpro­wa­dza­my ogra­ni­cze­nia zwią­za­ne z upraw­nie­nia­mi użyt­kow­ni­ków. Ten etap to pra­ca pro­jek­tan­tów UX i gra­fi­ków, spe­cja­li­stów od ergo­no­mii itp.

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