Architektura kodu aplikacji jako pierwszy etap tworzenia oprogramowania

Tym razem trosz­kę cięż­szy kali­ber, czy­li dywa­ga­cje o tym co powszech­nie jest okre­śla­ne jako meto­dy obiek­to­we i o tym skąd kon­flik­ty i nie­po­ro­zu­mie­nia” mię­dzy pro­gra­mi­sta­mi i ana­li­ty­ka­mi pro­jek­tan­ta­mi.?*?

Wprowadzenie

Literatura przed­mio­tu zawie­ra wie­le róż­nych spo­so­bów gru­po­wa­nia metod pro­gra­mo­wa­nia w ?para­dyg­ma­ty?. Autorzy z regu­ły sku­pia­ją się na tym, czym są pro­gra­my rozu­mia­ne jako zor­ga­ni­zo­wa­na lista pole­ceń dla maszy­ny. Mogą to być sekwen­cje pro­stych pole­ceń, mogą to być wyko­ny­wa­ne wg. okre­ślo­ne­go sce­na­riu­sza funk­cje. Typowym przy­kła­dem takie­go gru­po­wa­nia jest np. wykład (tu jego spis tre­ści) dostęp­ny w sie­ci Internet:

Wstęp
1.1 Przykład pierw­szy: pro­gra­mo­wa­nie impe­ra­tyw­ne
1.2 Przykład dru­gi: pro­gra­mo­wa­nie obiek­to­we
1.3 Przykład trze­ci: pro­gra­mo­wa­nie funk­cyj­ne
1.4 Przykład czwar­ty: pro­gra­mo­wa­nie w logi­ce (pro­gra­mo­wa­nie logicz­ne) ?1?

Wykład ten, z uwa­gi na to, że pocho­dzi ze stron mimów.edu .pl (Uniwersytet Warszawski, Wydział Informatyki) w moich oczach, po lek­tu­rze kil­ku­na­stu podob­nych, jest repre­zen­ta­tyw­nym dla wie­lu śro­do­wisk aka­de­mic­kich podejściem.

Programowanie strukturalne

Jest to para­dyg­mat pro­gra­mo­wa­nia opie­ra­ją­cy się na podzia­le kodu źró­dło­we­go pro­gra­mu na pro­ce­du­ry i hie­rar­chicz­nie uło­żo­ne blo­ki z wyko­rzy­sta­niem struk­tur kon­tro­l­nych w posta­ci instruk­cji wybo­ru i pętli. Rozwijał się w opo­zy­cji do pro­gra­mo­wa­nia wyko­rzy­stu­ją­ce­go pro­ste instruk­cje warun­ko­we i sko­ki. Programowanie struk­tu­ral­ne zwięk­sza czy­tel­ność kodu i uła­twia ana­li­zę pro­gra­mów, co sta­no­wi zna­czą­cą popra­wę w sto­sun­ku do trud­ne­go w utrzy­ma­niu ?spa­ghet­ti code? czę­sto wyni­ka­ją­ce­go z uży­cia instruk­cji go to”. Nadal jest to jed­nak dłu­ga lista sil­nie powią­za­nych procedur.

Metody struk­tu­ral­ne ana­li­zy i pro­jek­to­wa­nia bazu­ją na uzna­niu, że opro­gra­mo­wa­nie to stos funk­cji ope­ru­ją­cych na bazach (skła­dach) danych. Innymi sło­wy pod­sta­wo­we zało­że­nie to ist­nie­nie odręb­nych bytów jaki­mi są baza danych oraz funk­cje, któ­re na tych danych wyko­nu­ją ope­ra­cje. W meto­dach struk­tu­ral­nych two­rzy dwa się rodza­je mode­li: model pro­ce­su prze­twa­rza­nia i model struk­tu­ry danych. Pierwszy wyko­rzy­stu­je nota­cję DFD (Data Flow Diagram, np. nota­cja Gane?a- Sarsona) a dru­gi nota­cja ERD (Entity Relationship Diagram, np. nota­cja Martina) do mode­lo­wa­nia struk­tur rela­cyj­nych baz danych.

Rysunek 1 Diagram DFD w nota­cji Gene’a – Sarsona

Struktura apli­ka­cji w posta­ci tak zwa­nej ?czar­nej skrzyn­ki? zosta­ła poka­za­na na Rysunku 1. W meto­dach struk­tu­ral­nych, na pozio­mie opi­su archi­tek­tu­ry, apli­ka­cja ?dzie­lo­na jest? na pod­funk­cje (patrz Rysunek 2.).

Rysunek 2 Dekompozycja funkcji

Starsze pod­ręcz­ni­ki infor­ma­ty­ki i pro­gra­mo­wa­nia powo­łu­ją się na ?zasa­dę?: algo­ryt­my + struk­tu­ry danych = opro­gra­mo­wa­nie (apli­ka­cje). Kod zawie­ra­ją­cy funk­cje jest z regu­ły dzie­lo­ny jest na czę­ści zwa­ne ?pod­pro­gram?, jed­nak nie­za­leż­nie od tego jak jest zor­ga­ni­zo­wa­ny, jest to zwar­ty i nie­po­dziel­ny sys­tem funk­cji i algo­ryt­mów, któ­ry zapi­su­je i odczy­tu­je dane ze współ­dzie­lo­ne­go ?maga­zy­nu danych?. Najczęściej tym maga­zy­nem jest rela­cyj­nie zor­ga­ni­zo­wa­na baza danych?2?, czy­li sys­tem powią­za­nych tablic, w któ­rym usu­wa się redun­dan­cje i two­rzy trwa­łe związ­ki logicz­ne mię­dzy tak zor­ga­ni­zo­wa­ny­mi danymi.

Modelowania struk­tur rela­cyj­nych baz danych (nota­cja ERD, Entity Relationship Diagram, tu nota­cja Martina)

Architektura taka nie spra­wia więk­szych pro­ble­mów do momen­tu gdy apli­ka­cja nie zaczy­na się roz­ra­stać i nie poja­wia się potrze­ba wpro­wa­dza­nia kolej­nych nowych lub zmie­nio­nych ele­men­tów mecha­ni­zmu jej dzia­ła­nia. Wtedy każ­da inge­ren­cja w tak zor­ga­ni­zo­wa­ną archi­tek­tu­rę doty­czy pra­wie zawsze całej apli­ka­cji. Stabilne kie­dyś oto­cze­nie (śro­do­wi­sko użyt­ko­wa­nia tych apli­ka­cji) pozwa­la­ło na pro­jek­to­wa­nie opro­gra­mo­wa­nia, od któ­re­go nikt nie ocze­ki­wał, że pozwo­li na łatwe i szyb­kie wpro­wa­dza­nie zmian. Po dru­gie, two­rze­niem opro­gra­mo­wa­nia zaj­mo­wa­ły się małe zespo­ły pro­gra­mi­stów, zaś logi­ka prze­twa­rza­nia pole­ga­ła raczej na reali­zo­wa­niu małej licz­by typów ope­ra­cji na wiel­kich ilo­ściach danych, to były głow­nie pro­jek­ty inży­nier­skie a nie badaw­cze. Zamawiający (tak zwa­ny dzi­siaj ?biz­nes?) musiał jedy­nie spi­sać dane i ope­ra­cje oraz wzo­ry (for­mu­ły) z jakich uży­ciem były one przeliczane.

Zmiana paradygmatu

Rosnąca zło­żo­ność opro­gra­mo­wa­nia wymu­si­ła szu­ka­nie nowych roz­wią­zań. Początkowo dzie­lo­no kod apli­ka­cji na sepa­ro­wa­ne czę­ści – modu­ły, jed­nak nadal sta­no­wi­ły one jed­ną całość z powo­du pra­cy z dany­mi w posta­ci jed­nej zwar­tej struk­tu­ry, jaką jest współ­dzie­lo­na rela­cyj­na baza danych. Fakt ten czę­sto jest postrze­ga­ny jako zale­ta: wska­zu­je się na brak redun­dan­cji, łatwy spo­sób uzy­ska­nia spój­no­ści danych, współ­dzie­le­nie jako łatwą inte­gra­cję. Problem w tym, że duże apli­ka­cje ope­ru­ją w wie­lu kon­tek­stach, co powo­du­je, że współ­dzie­lo­na baza danych o usta­lo­nej struk­tu­rze, musi sta­no­wić kom­pro­mis. Np. dane sta­no­wią­ce zapis kolej­nych zaku­pów amor­ty­zo­wa­nych środ­ków trwa­łych mają inną struk­tu­rę i logi­kę wza­jem­nych powią­zań, niż te same dane w kon­tek­ście zło­żo­nych kon­struk­cji mecha­nicz­nych jaki­mi są te środ­ki trwa­łe. Innym przy­kła­dem obra­zu­ją­cym kwe­stie kon­tek­sto­wo­ści jest przy­kład na blo­gu Martina Fowlera.?3?

Rysunek 3 Granice kon­tek­stu i zmia­na per­spek­ty­wy pojęć ?3?.

Jak widać na Rysunku 3., mamy tu dwa kon­tek­sty i redun­dan­cje (poję­cia Customer i Produkt powie­lo­ne po obu stro­nach: w obu dzie­dzi­nach). Powyższe powin­no być pod­sta­wą do podzia­łu pro­jek­tu na dwa odręb­ne kom­po­nen­ty z wła­sny­mi (nie współ­dzie­lo­ny­mi) dany­mi. Jak widać każ­dy kom­po­nent ope­ru­je poję­cia­mi Customer i Produkt, jed­nak inny jest ich kon­tekst. Inne cechy dzie­dzi­no­we tych pojęć nie są (nie powin­ny być) współ­dzie­lo­ną infor­ma­cją w jed­nej bazie danych, oba kom­po­nen­ty będą mia­ły swo­je odręb­ne mode­le danych, zapew­ne o róż­nią­cej struk­tu­rze. Powód pierw­szy to inne związ­ki poję­cio­we i być może nawet inne defi­ni­cje pojęć. Produkt w kon­tek­ście sprze­da­ży ma nazwę, cenę, dostęp­ność itp. Produkt w kon­tek­ście uszko­dzeń ma numer seryj­ny, wer­sję, użyt­kow­ni­ka itp. Inne będą regu­ły biz­ne­so­we w każ­dym kom­po­nen­cie. Drugi powód to łatwa dostęp­ność na ryn­ku spe­cja­li­zo­wa­nych pro­duk­tów typu CRM i TicketXXX, szu­ka­nie (two­rze­nie) jed­ne­go ?pakie­tu zin­te­gro­wa­ne­go? będzie bar­dzo trud­ne, bo kon­tek­stów sprze­da­ży a potem obsłu­gi uszko­dzeń czy rekla­ma­cji, jako pary, będą tysią­ce warian­tów. Wytworzenie (zakup) osob­no, i inte­gra­cja dwóch odpo­wied­nio dobra­nych kom­po­nen­tów (apli­ka­cji), będą znacz­nie łatwiejsze.

Powoli zaczę­ły swe­go cza­su powsta­wać apli­ka­cje dzie­dzi­no­we, jed­nak nadal wewnętrz­nie mia­ły one opi­sa­ne wyżej wady współ­dzie­le­nia danych w jed­nej bazie. Do tego ich inte­gra­cja pole­ga­ła na wza­jem­nym się­ga­niu do danych co sta­no­wi­ło bar­dzo duży pro­blem z powo­du róż­nych struk­tur tych danych, zaś wymia­na jed­nej z nich na inną wyma­ga­ła opra­co­wa­nia od nowa całej kon­cep­cji inte­gra­cji współ­dzie­lo­nych danych co poka­za­no na Rysunku 4.

Rysunek 4 Integracja apli­ka­cji strukturalnych

Obiektowy paradygmat

Co cie­ka­we powsta­nie metod obiek­to­wych nie było szu­ka­niem spo­so­bu usu­nię­cia wad sys­te­mów struk­tu­ral­nych. Pierwsze obiek­to­we narzę­dzia powsta­ły już w latach sześć­dzie­sią­tych XX w. narzę­dzia i pro­gra­my struk­tu­ral­ne tak­że powsta­ją do tej pory.

Do obec­nej popu­lar­no­ści metod obiek­to­wych dopro­wa­dzi­ły dwie ścież­ki: pro­blem rosną­cej zło­żo­no­ści kodu apli­ka­cji oraz potrze­ba utrzy­ma­nia zro­zu­mie­niu ?tego czym jest ta apli­ka­cja? po stro­nie zamawiającego.

Proces, powszech­nie zwa­ny ?zbie­ra­niem wyma­gań?, sta­je się coraz bar­dziej skom­pli­ko­wa­ny i ryzy­kow­ny, w mia­rę jak rośnie zło­żo­ność tych systemów.

Wymagania na opro­gra­mo­wa­nie nali­cza­ją­ce wyna­gro­dze­nia tysiąc­om pra­cow­ni­ków to ?jeden wzór? na nali­cze­nie wyna­gro­dze­nia oraz pew­na licz­ba cech jako­ścio­wych takich jak wydaj­ność czy dostęp­ność. Jednak opi­sa­nie tą meto­dą jed­nej” apli­ka­cji, ope­ru­ją­cej dzie­siąt­ka­mi doku­men­tów o róż­nych struk­tu­rach i ogrom­nej ilo­ści zależ­no­ści mię­dzy nimi, z pomo­cą ?listy cech? zaczy­na przy­bie­rać postać setek, a nie raz tysię­cy, linii i danych w tabe­lach. Przy takiej ilo­ści wyma­gań” prak­tycz­nie żaden spo­sób ich orga­ni­za­cji nie wpro­wa­dza war­to­ści doda­nej, zaś ich licz­ba prak­tycz­nie nie pozwa­la na kon­tro­lę kom­plet­no­ści i niesprzeczności.

Popatrzmy na komen­tarz auto­ra wykła­du?1? do obiek­to­we­go programowania:

W pro­gra­mo­wa­niu obiek­to­wym pro­gram to zbiór poro­zu­mie­wa­ją­cych się ze sobą obiek­tów, czy­li jed­no­stek zawie­ra­ją­cych pew­ne dane i umie­ją­cych wyko­ny­wać na nich pew­ne ope­ra­cje
- Ważną cechą jest tu powią­za­nie danych (czy­li sta­nu) z ope­ra­cja­mi na nich (czy­li pole­ce­nia­mi) w całość, sta­no­wią­cą odręb­ną jed­nost­kę ? obiekt.
- Cechą nie mniej waż­ną jest mecha­nizm dzie­dzi­cze­nia, czy­li moż­li­wość defi­nio­wa­nia nowych, bar­dziej zło­żo­nych obiek­tów, na bazie obiek­tów już ist­nie­ją­cych.
Zwolennicy pro­gra­mo­wa­nia obiek­to­we­go uwa­ża­ją, że ten para­dyg­mat dobrze odzwier­cie­dla spo­sób, w jaki ludzie myślą o świe­cie
- Nawet jeśli pogląd ten uzna­my za prze­jaw pew­nej egzal­ta­cji, to nie­wąt­pli­wie pro­gra­mo­wa­nie obiek­to­we zdo­by­ło ogrom­ną popu­lar­ność i wypa­da je uznać za para­dyg­mat obec­nie dominujący.

W cyto­wa­nym tek­ście widać ste­reo­ty­po­we podej­ście autora:

meto­dy obiek­to­we two­rze­nia opro­gra­mo­wa­nia, opie­ra­ją się na wyróż­nia­niu w two­rzo­nym opro­gra­mo­wa­niu dwóch rodza­jów skła­do­wych: pasyw­nych odzwier­cie­dla­ją­cych fakt prze­cho­wy­wa­nia w sys­te­mie pew­nych danych oraz skła­do­wych aktyw­nych odzwier­cie­dla­ją­cych fakt wyko­ny­wa­nia w sys­te­mie pew­nych ope­ra­cji. Metody obiek­to­we wyróż­nia­ją w sys­te­mie skła­do­we, któ­re łączą w sobie moż­li­wość prze­cho­wy­wa­nia danych oraz wyko­ny­wa­nia ope­ra­cji? (źr. wikipedia).

Schematycznie moż­na to przed­sta­wić tak:

Podejście, któ­re nazwę pro­gra­mi­stycz­nym, to uzna­nie, że trze­ba podzie­lić dużą apli­ka­cję na mniej­sze odręb­ne kom­po­nen­ty, z któ­rych każ­dy ma ?swo­je funk­cje i dane?. Tu tak­że pod­kre­śla­na jest kwe­stia re-uży­cia kodu w posta­ci tak zwa­ne­go dzie­dzi­cze­nia jako ?mecha­ni­zmu defi­nio­wa­nia nowych, bar­dziej zło­żo­nych obiek­tów, na bazie obiek­tów już ist­nie­ją­cych? .

Zupełnie inną dro­gą jest podej­ście opar­te na uzna­niu, że świat rze­czy­wi­sty to okre­ślo­ny mecha­nizm, któ­ry da się odwzo­ro­wać jako pew­na abs­trak­cja za pomo­cą kodu (jego struk­tu­ry). Tu struk­tu­ra kodu jest kon­se­kwen­cją struk­tu­ry tego obsza­ru świa­ta rze­czy­wi­ste­go?, któ­re­go doty­czy two­rzo­ne opro­gra­mo­wa­nie (o czym już na swo­im blo­gu nie raz pisałem).

Skutek jest ?taki sam?: pro­gram stwo­rzo­ny zgod­nie z obiek­to­wym para­dyg­ma­tem będzie się owszem skła­dał z klas obiek­tów, któ­re komu­ni­ku­ją się wza­jem­nie. Jednak podej­ście zorien­to­wa­ne na dzie­le­nie dużej apli­ka­cji na pod­pro­gra­my trak­tu­je obiek­ty jako ?jakieś? kom­po­nen­ty zawie­ra­ją­ce w sobie kod funk­cji i dane na jakich one ope­ru­ją. Podejście zorien­to­wa­ne na mode­lo­wa­nie ?świa­ta rze­czy­wi­ste­go? zaowo­cu­je obiek­ta­mi sta­no­wią­cy­mi abs­trak­cje (mode­le) ele­men­tów świa­ta rze­czy­wi­ste­go. Struktura takie­go kodu w obu przy­pad­kach będzie obiek­to­wa” ale jej sens nie raz jest skraj­nie inny np. obiekt fak­tu­ra będzie zawie­rał dane o sprze­da­ży ale nie będzie miał ope­ra­cji ?nowa fak­tu­ra?, bo fak­tu­ry nie two­rzą nowych fak­tur? (ani nie nio­są infor­ma­cji o tym jak powsta­wa­ły). Faktury będą two­rzo­ne przez inny obiekt np. Twórca fak­tur (albo jak w nie­któ­rych wzor­cach: fabry­ka fak­tur).?4?

Od lat sześć­dzie­sią­tych pro­wa­dzo­ne są pra­ce nad meto­da­mi obiek­to­wy­mi w inży­nie­rii opro­gra­mo­wa­nia, powsta­je języ­ka SIMULA w 1967 roku. W 1968 roku opu­bli­ko­wa­no pierw­sze ofi­cjal­ne wyda­nie Ogólnej Teorii Systemów Ludwiga von Bertalanffy’ego (publi­ka­cje na jej temat poja­wia­ły się od już 1964 roku). Teoria sys­te­mów mówi, że ?sys­tem to współ­pra­cu­ją­ce obiek­ty?, język SIMULA powstał do two­rze­nia (pro­gra­mów) symu­la­cji obiek­tów świa­ta rzeczywistego.

Oba wska­za­ne podej­ścia są zna­ne od lat, jed­nak podej­ście ?inży­nier­skie? (dzie­le­nie duże­go kodu na małe kawał­ki) domi­nu­je, nie tyl­ko jak widać w sys­te­mie kształcenia.

Ogólna teo­ria sys­te­mów trak­tu­je wszyst­ko jak ?sys­tem? (współ­pra­cu­ją­ce obiek­ty). Z zewnątrz sys­tem to obiekt reagu­ją­cy na bodź­ce. Reakcja ta może być opi­sa­na mecha­ni­zmem jej powsta­wa­nia, to wewnętrz­na struk­tu­ra sys­te­mu. Jeżeli uznać, że opro­gra­mo­wa­nie (i kom­pu­ter) zastę­pu­je okre­ślo­ną rze­czy­wi­stość (np. mecha­nicz­ny zegar zastą­pio­ny pro­gra­mem wyko­ny­wa­nym w kom­pu­te­rze) to moż­na przy­jąć, że kom­pu­ter to maszy­na abs­trak­cyj­na, jej imple­men­ta­cja reali­zu­je kon­kret­ne sys­te­my i (lub) ich kom­po­nen­ty?5?.

Nie cho­dzi więc o to by podzie­lić opro­gra­mo­wa­nie na ?skła­do­we, któ­re łączą w sobie moż­li­wość prze­cho­wy­wa­nia danych oraz wyko­ny­wa­nia ope­ra­cji?. Chodzi o to by mecha­nizm, o dowie­dzio­nej popraw­no­ści, zaim­ple­men­to­wać w okre­ślo­nej wybra­nej technologii. 

Chodzi też o to by nie uda­wać, że pro­gra­mo­wa­nie jako ?podzie­lo­ne na obiek­ty? par­tie kodu, nadal korzy­sta­ją­ce z jed­nej wspól­nej bazy danych, róż­ni się czym­kol­wiek od ?struk­tu­ral­ne­go kodu?. Chodzi o to by kod pro­gra­mu fak­tycz­nie imple­men­to­wał okre­ślo­ny (zba­da­ny i opi­sa­ny) mechanizm.

Tak więc ?obiek­to­wy para­dyg­mat? to nie ?nowe pro­gra­mo­wa­nie”, to archi­tek­tu­ra kodu: ?obiek­to­wa? archi­tek­tu­ra???.

Proces pro­jek­to­wa­nia opro­gra­mo­wa­nia, idąc tro­pem ana­li­zy sys­te­mo­wej i opi­sa­nia mecha­ni­zmu dzia­ła­nia tego cze­goś”, zaczy­na się już na eta­pie ana­li­zy. Programista imple­men­tu­je model a nie wymy­śla pro­gram”. Oczywiście pod warun­kiem, że mamy tu na myśli ana­li­zę obiek­to­wą i pro­jek­to­wa­nie sys­te­mu a nie jakiś podział kodu na klasy”.

Na zakoń­cze­nie jeden z moich ulu­bio­nych cyta­tów na temat ana­li­zy i pro­jek­to­wa­nia obiektowego:

(źr. Martin Fowler, Analysis Patterns, 1997)
(źr. Martin Fowler, Analysis Patterns, 1997)?6?

  1. ?*?
    Artykuł został opu­bli­ko­wa­ny w mate­ria­łach pokon­fe­ren­cyj­nych: https://www.academia.edu/37284192/Materiały_pokonferencyjne_III_Ogólnopolskiej_Konferencji_Interdyscyplinarnej_Współczesne_zastosowania_informatyki_Architektura_kodu_aplikacji_jako_pierwszy_etap_tworzenia_oprogramowania
  2. ???
    Wielu auto­rów przy­wo­łu­je tu poję­cie kom­po­nen­tów a nie obiek­tów. Komponentem jest tu każ­dy samo­dziel­ny, komu­ni­ku­ją­cy się z oto­cze­niem, obiekt nie­za­leż­nie od wiel­ko­ści i stop­nia złożoności. 

Źródła:

  1. 1.
    Paradygmaty programowania/Wykład 1: Co to jest para­dyg­mat pro­gra­mo­wa­nia? – Studia Informatyczne. MIMUW. http://wazniak.mimuw.edu.pl/index.php?title=Paradygmaty_programowania/Wykład_1:_Co_to_jest_paradygmat_programowania%3F. Accessed July 16, 2017.
  2. 2.
  3. 3.
    Fowler M. bli­ki: BoundedContext. mar​tin​fow​ler​.com. https://​mar​tin​fow​ler​.com/​b​l​i​k​i​/​B​o​u​n​d​e​d​C​o​n​t​e​x​t​.​h​tml. Published January 15, 2014. Accessed July 16, 2017.
  4. 4.
    Żeliński J. Analiza biz­ne­so­wa. Praktyczne mode­lo­wa­nie orga­ni­za­cji. one​press​.pl. http://​one​press​.pl/​v​i​e​w​/​2​2​3​9​k​/​s​f​o​m​o​d​.​htm. Accessed July 16, 2017.
  5. 5.
  6. 6.
    Martin Fowler, Analysis Patterns, 1997.

Inne artykuły na podobny temat

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.