Dwa tygo­dnie temu, na kon­fe­ren­cji o jako­ści sys­te­mów IT, pre­zen­to­wa­łem mię­dzy inny­mi dwa poniż­sze wykresy:

Koszty rozwoju


Pierwszy wykres jest bar­dzo popu­lar­ny w lite­ra­tu­rze przed­mio­tu, tu jeden z wie­lu przy­kła­dów. Powołam się na nie­go później.

Effective software delivery. White paper. May 2009

Drugi jest wyni­kiem moich stu­diów lite­ra­tu­ry , wła­snych badan i doświad­cze­nia i wła­śnie o nim nie­co wię­cej. Wyjaśnię jak powstał.

W zasa­dzie wystar­czy uznać, że jeże­li speł­nie­nie zasa­dy „[[open clo­sed prin­ci­ple in object orien­ted softwa­re]]” (archi­tek­tu­ra sys­te­mu jest otwar­ta na roz­sze­rze­nia i zamknię­ta na zmia­ny) jest moż­li­we, to kod tak zbu­do­wa­nej apli­ka­cji rośnie” linio­wo, a koszt roz­wo­ju podob­nie. Początkowy koszt, to koszt opra­co­wa­nia szkie­le­tu (zwa­ne­go [[core doma­in]]). To wła­śnie – w apli­ka­cjach kon­stru­owa­nych zgod­nie z [[zasa­da­mi SOLID]] – powo­du­je, że koszt począt­ko­wy jest rela­tyw­nie wyż­szy niż koszt archi­tek­tu­ry budo­wa­nej ad-hoc” (ozna­czo­nej ???).

Nie mam ambi­cji two­rze­nia przy­kła­du brzyd­kiej archi­tek­tu­ry”, chy­ba już nie umiem 😉 dla­te­go poni­żej tyl­ko struk­tu­ra apli­ka­cji (archi­tek­tu­ra kom­po­nen­tu Model/MVC) w obiek­to­wym para­dyg­ma­cie (apli­ka­cja to współ­pra­cu­ją­ce obiek­ty) zgod­na z SOLID:

Obiektowy model dziedziny Zasada SOLID
Przykład archi­tek­tu­ry na bazie wzor­ca BCE (BCCE)

Model ten powstał z uży­ciem blo­ków funk­cjo­nal­nych wzor­ca BCE (opi­sa­łem go tu: Wzorzec ana­li­tycz­ny Boundary Control Entity). Dla wyja­śnie­nia: powyż­szy dia­gram to w peł­ni popraw­ny Model dzie­dzi­ny wyko­na­ny z uży­ciem dia­gra­mu klas UML, kla­sy mają ste­reo­ty­py boun­da­ry, con­trol i enti­ty (powy­żej od lewej do pra­wej), ste­reo­ty­py te są repre­zen­to­wa­ne sym­bo­la­mi opi­sa­ny­mi (iko­na­mi) w BCE. Kilka cech tej architektury:

  1. każ­dy przy­pa­dek uży­cia ma dedy­ko­wa­ną kla­sę (ta połą­czo­na z akto­rem) odpo­wie­dzial­ną za jego inter­fejs i sce­na­riusz (ale nie logi­kę biznesową!),
  2. sce­na­riusz przy­pad­ku uży­cia to recep­ta” na to, kie­dy i cze­go wewnątrz apli­ka­cji nale­ży użyć do reali­za­cji celu użytkownika,
  3. to co potra­fi” apli­ka­cja to usłu­gi wewnętrz­ne (logi­ka biznesowa),
  4. to co apli­ka­cja musi wie­dzieć” zapa­mię­ta­ło się (jest prze­cho­wy­wa­ne) w repozytoriach,
  5. żad­ne infor­ma­cje nie są, logicz­nie ani w szcze­gól­no­ści fizycz­nie, współ­dzie­lo­ne: każ­de repo­zy­to­rium, powy­żej są trzy, jest w 100% her­me­ty­zo­wa­ne (imple­men­ta­cja repo­zy­to­riów to abso­lut­nie! nie jest jed­na współ­dzie­lo­na rela­cyj­na baza danych i mapo­wa­nie ORM!).

Widać (mam nadzie­ję na tym dość pro­stym sche­ma­cie), że każ­dy przy­pa­dek uży­cia to odręb­ny ser­wis”, prak­tycz­nie nie­za­leż­na usłu­ga (u Fowlera nazy­wa­ne mikro­ser­wi­sa­mi). Są od sie­bie cał­ko­wi­cie odse­pa­ro­wa­ne, co naj­wy­żej korzy­sta­ją z tych samych spe­cja­li­zo­wa­nych usług wewnętrz­nych (np. z gene­ra­to­ra pli­ków PDF będzie korzy­sta­ła każ­da usłu­ga ope­ru­ją­ca na doku­men­tach do dru­ku). Dodanie kolej­ne­go przy­pad­ku uży­cia w ogó­le nie wpły­wa na resz­tę apli­ka­cji (zale­ta her­me­ty­za­cji), ewen­tu­al­ne redun­dan­cje są raczej zba­wie­niem niż wadą, gdyż każ­da usłu­ga ma swój kon­tekst i wła­sny cykl życia, i jakie­kol­wiek współ­dzie­le­nie tre­ści (nie mylić z wyko­rzy­sta­niem tych samych) raczej zmu­si do (zgni­łe­go) kompromisu.

Współdzielenie danych naj­czę­ściej przy­no­si szko­dy, np. współ­dzie­le­nie listy pro­duk­tów pomię­dzy zamó­wie­niem i fak­tu­rą powo­du­je zależ­ność unie­moż­li­wia­ją­cą wysta­wie­nie fak­tu­ry na pro­duk­ty inne (w innej ilo­ści) niż na tym zamó­wie­nia (nie takie rzad­kie zja­wi­sko w dostęp­nych na ryn­ku sys­te­mach ERP). Utworzenie fak­tu­ry poprzez sko­pio­wa­nie (wyko­rzy­sta­nie) zawar­to­ści Zamówienia, pozwa­la na jej (fak­tu­ry) dowol­ną mody­fi­ka­cję bez potrze­by zmia­ny Zamówienia (żąda­nia powtór­ne­go jego przy­sła­nia lub o zgro­zo, wewnętrz­nej korek­ty!). Współdzielenie danych firm pomię­dzy np. fak­tu­ra­mi i reje­strem kon­tra­hen­tów, skut­ku­je pro­ble­mem gdy aktu­ali­za­cja adre­su kon­tra­hen­ta prze­no­si się na histo­rycz­ne fak­tu­ry. Owszem może nam się przy­tra­fić koszt nowej usłu­gi wewnętrz­nej, ale zro­bi­my to bez jakiej­kol­wiek inge­ren­cji w dotych­cza­so­wą logi­kę (i kod).

Aplikacje, któ­rych archi­tek­tu­ra wewnętrz­na bazu­je na współ­dzie­lo­nych danych, rela­cyj­nej jed­nej bazie danych (jeden spój­ny sys­tem tablic rela­cyj­nej bazy danych pod” apli­ka­cją), gęstej sie­ci wewnętrz­nych zależ­no­ści, wyma­ga­ją – dla doda­nia nowej usłu­gi lub zmia­ny ist­nie­ją­cej – pra­wie zawsze czę­ścio­we­go lub cał­ko­wi­te­go re-fak­to­rin­gu, a w skraj­nych przy­pad­kach nawet migra­cji danych do nowej ich struk­tu­ry. W efek­cie, to co użyt­kow­nik postrze­ga jako roz­sze­rze­nie, dla dewe­lo­pe­ra sta­no­wi pra­co­chłon­ny refak­to­ring, tym bar­dziej pra­co­chłon­ny im więk­sza ta apli­ka­cja. Z tego powo­du kosz­ty wpro­wa­dza­nia zmian do tak stwo­rzo­nej apli­ka­cji są tym więk­sze im więk­sza i zło­żo­na jest ta apli­ka­cja (czer­wo­na linia na wykre­sie kosz­tu roz­sze­rze­nia funkcjonalności).

Pisanie opro­gra­mo­wa­nia ad-hoc, bez prze­my­śla­nej logi­ki i archi­tek­tu­ry cało­ści, pro­wa­dzi do powsta­wa­nia tak zwa­ne­go „[[dłu­gu archi­tek­to­nicz­ne­go]]” (ana­lo­gicz­nie do [[dług tech­no­lo­gicz­ny]]). To dla­te­go bar­dzo czę­sto źle poj­mo­wa­ne agi­le” pozwa­la bar­dzo szyb­ko uzy­skać pierw­sze efek­ty, nie­ste­ty oku­pio­ne bar­dzo kosz­tow­nym póź­niej­szym utrzy­ma­niem i roz­wo­jem takiej apli­ka­cji. Chyba, że pro­dukt taki potrak­to­wa­ny zosta­nie jako efe­me­ry­da albo jako pro­to­typ odrzucany.

Niestety wie­le sys­te­mów ERP i i nie tyl­ko, powsta­ło w latach 90’tych, mają one nie­ste­ty scen­tra­li­zo­wa­ną archi­tek­tu­rę struk­tu­ral­ną (jed­na baza danych i nad nią” funk­cje prze­twa­rza­ją­ce te dane). Efekty tego widać przy wdro­że­niach, w któ­rych dopusz­czo­no tak zwa­ną kasto­mi­za­cje sys­te­mu, czy­li wła­śnie wpro­wa­dza­nie, nie raz bar­dzo wie­lu, zmian. To bar­dzo kosz­tow­ne pro­jek­ty o prak­tycz­nie nie­prze­wi­dy­wal­nym budże­cie. Niestety współ­dzie­le­nie danych wewnątrz takie­go sys­te­mu jest jego poważ­ną wadą a nie – jak to zachwa­la­ją ich dostaw­cy – zaletą…

Jarosław Żeliński

BIO: Od roku 1991 roku, nieprzerwanie, realizuję projekty z zakresu analiz i projektowania systemów, dla urzędów, firm i organizacji. Od 1998 roku prowadzę także samodzielne studia i prace badawcze z obszaru analizy systemowej i modelowania (modele jako przedmiot badań: ORCID). Od 2005 roku, jako nieetatowy wykładowca akademicki, prowadzę wykłady i laboratoria (ontologie i modelowanie systemów informacyjnych, aktualnie w Wyższej Szkole Informatyki Stosowanej i Zarządzania pod auspicjami Polskiej Akademii Nauk w Warszawie. Oświadczenia: moje badania i publikacje nie mają finansowania z zewnątrz, jako ich autor deklaruję brak konfliktu interesów.

Dodaj komentarz

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