Tag Archive : video

Wprowadzenie

Ontologia jako narzędzie tworzenia “modeli świata”, jest bardzo dobrym narzędziem do projektowania danych, zorganizowanych – w łatwe do zarządzania w bazach NoSQL – dokumenty. Niedawno napisałem:

Czy opra­co­wa­nie onto­lo­gii jest łatwe? Nie, nie jest. Czy zła onto­lo­gia szko­dzi? Tak, potra­fi dopro­wa­dzić do fia­ska pro­jek­tu infor­ma­tycz­ne­go.

źr.;: Ontologia czyli jak się to robi

Po co to wszystko? Obecnie często mówimy o Big Data, czyli o masowo gromadzonych danych. Ich gromadzenie wymaga opracowania struktury ich gromadzenia i zarządzania nimi, bez tego powstanie “stos nieskatalogowanych dokumentów”. Proces gromadzenia danych jest stratny, więc dane te można zgromadzić raz, przepisanie ich do nowej struktury jest możliwe tylko gdy nowa struktura jest prostsza (przepisywanie do identycznej nie ma sensu) więc każda migracja to utrata informacji. Innymi słowy: architekt danych, podobnie jak saper, myli się tylko raz.

Ontologia

Przypomnijmy definicję:

ontologia: lista pojęć i kategorii z jakiegoś obszaru tematycznego, która pokazuje związki między nimi

Generalnie, zgodnie z zasadą wyłączonego środka, każde dwa pojęcia mozna połączyć w zdanie albo generalizacją albo predykatem. Kolejna zasada: w poprawnej ontologii, wstawienie w zdaniu, w miejsce pojęcia, jego typu (specjalizacja), zachowuje prawdziwość tego zdania. Trzecia: zdanie tworzą także jedno pojęcie i predykat. Przykłady odpowiednio:

  1. jeżeli “ratler to rasa (typ) psa”
  2. a także “mały pies to także pies”
  3. oraz “pies szczeka na listonosza”
  4. więc “ratler szczeka na listonosza”
  5. także “mały pies szczeka na listonosza”
  6. oraz “pies szczeka”

Wszystkie powyższe zdania to zdania prawdziwe i sensowne w języku polskim. Są to zdania prawdziwe w sensie “tak sią (generalnie) dzieje, że… “, są to fakty jeżeli zdanie jest relacją. Patrz:

W The Philosophy of Logical Atomism Russell pisze: Jeśli mówię „Pada”, to to, co ja mówię jest prawdziwe przy pewnych warunkach pogodowych a jest fałszywe przy innych. Warunki pogodowe, które czynią moje stwierdzenie prawdziwym (lub fałszywym w innym przypadku), są tym, co nazywam faktem” [zotpressInText item=”{5085975:52F4HLJ6}”]

Modelowanie

Wśród wielu znanych metod modelowania ontologii jest OntoUML [zotpressInText item=”{5085975:V8JX39Y2},{5085975:5K34YGSS}”]. Moim zdaniem ma pewne wady: autorzy wprowadzają pojęcie ‘event’ mające takie cechy jak początek i koniec (wartością tych atrybutów jest czas: timestamp). Uważam, że stwarza to pewien problem z klasyfikacją treści takiego komunikatu. Po drugie, jeżeli uznamy, że przestrzegamy zasady “nie lubimy pustych pól” (bazy danych nie zawierają pól/atrybutów bez wartości) to ‘event’ łamie tę zasadę, bo wartość zadeklarowanego pola “end event” będzie pusta do momenty zakończenia “zdarzenia”. Jednym z ciekawszych podejść do ontologii, jej modelowanie i integracją z modelami systemów (MDA, SysML, UML) opisali w swojej pracy Devedzic i inni [zotpressInText item=”{5085975:K6Z5L6JM},{5085975:K2PIVCKQ}”] z czego także tu korzystam.

W publikacji na temat klasyfikacji i jednoznaczności opisu [zotpressInText item=”{5085975:9KMR85JV}”] opisywałem metodę dzielenia informacji wg. kontekstu, jakim jest sklasyfikowanie treści jako opisu obiektu (ten trwa w czasie) oraz faktu (nie trwa w czasie). Zdanie “Dom ma cztery okna i czerwony dach” jest prawdziwe mimo upływu czasu, zawsze będzie wypowiadane w czasie teraźniejszym. Zdanie “w Dom uderzył piorun” jest prawdziwe ale zawsze będzie wypowiadane w czasie przeszłym. Obiekty trwają w czasie, ich stan może się zmieniać: “Po przemalowaniu (fakt) dom ma zielony dach” (i to trwa). Wszystko to co trwa w czasie, jest ograniczane faktami, w szczególności fakt powstania rzeczy (obiektu) i fakt jego “zniszczenia”, w międzyczasie mogą mieć miejsce fakty zmieniające stan rzeczy (obiektu, np. zmiana koloru).

Generalizując: obiekty trwają w czasie zaś fakty nie. Początek i koniec trwania obiektu to dwa kluczowe fakty z “jego życia” (cykl życia obiektu) a nie “event” mający początek i koniec. W “życiu” obiektu mogą wystąpić inne fakty. Cechy obiektu to jego własności (kolor, waga i wiele innych itp.), cechami faktów są moment w czasie (time stamp) oraz to jakiego obiektu (obiektów) dotyczyły.

Ontologia (SBVR, diagram faktów)

W systemach informacyjnych mamy do czynienia z gromadzeniem wiedzy o świecie oraz z gromadzeniem sprawozdań. Powyżej ontologia czyli pojęciowy model wycinka świata. Zdanie “pies szczeka na listonosza” a także “pies szczeka” to ogólna wiedza o psach. Zdanie “listonosz boi się psa” to ogólna wiedza o listonoszach. Sprawozdaniem było by tu zdanie: “mały pies, pudel, szczekał na listonosza od godzony 16:16 do godziny 16:18” (można by jeszcze podać adres).

Ontologia, jako językowy opis świata, to metamodel zdań opisujących pewną klasę obiektów i zdarzeń. Sprawozdanie mówiące, że konkretny pies, w określonym okresie czasu, szczekał na konkretnego listonosza (w konkretnym miejscu) to taka właśnie instancja (wystąpienie).

Projektowanie architektury danych

Jaką architekturę powinien mieć “dokument” będący treścią tego sprawozdania?

Poniżej trzy etapy analizy.

Modele wiedzy oparte na ontologii (diagramy klas, UML, opracowanie własne autora).

Ogólnie można powiedzieć, że predykaty (fakty zdaniotwórcze) dotyczą obiektów: zbieramy informacje (wiedzę) o tym, kiedy pies szczekał na ludzi, jaki pies i na jakich ludzi szczekał. To rysunek a. powyżej, możemy go nazwać koncepcją. Zapisanie takiej informacji wymaga zaprojektowania trzech repozytoriów: pies, człowiek, predykat. Powiązanie psa z człowiekiem jest zapisane jako atrybuty predykatu (rys. b.). To projekt architektury danych i logiki ich wiązania. Bardziej uniwersalny model pokazano na rys. c., wymagał by on uzupełnienia “bazą szablonów obiektów” (struktury agregatów opisujacych różne typy obiektów) z uwagi na to, że różne obiekty mogą mieć różne cechy. Tu pokazano je w uproszczeniu jako atrybuty, jednak realny projekt dziedzinowy były już bardziej precyzyjny i rozbudowany.

Powyższe można zapisać w bazie NoSQL, w w bazie grafowej obiekty były by węzłami a predykaty krawędziami. Detale obiektów mogą być agregatami w bazie dokumentowej.

Rola ontologii w projektach

Kluczową rolą i celem tworzenia ontologii jest wspólny słownik i zrozumienie pojęć. Ontologia pełni rolę centralnej współdzielonej przestrzeni pojęciowej (namespace) i wiedzy dziedzinowej (np. reguły biznesowe). Wszystkie systemy w organizacji (bardzo często od różnych producentów) mają – każdy swój – wewnętrzny i lokalnie spójny system pojęciowy (namespace). Jakakolwiek ich integracja (wymiana komunikatów między systemami) wymaga mapowania synonimów w komunikatach (nazwy pój, ich wartości, robi to adapter, bardzo często jest to implementowane jako szyna integracyjna ESB):.

Zarządzanie systemem pojęć

Podsumowanie

Uważam, że ontologie nie wymagają skomplikowanych metamodeli takich jak ww. OntoUML czy bardziej skomplikowanych, opartych na rozbudowanych taksonomiach i modelu UFO [zotpressInText item=”{5085975:743UXHMB}”].

Gromadzenie wiedzy to albo wiedza “generalna” opisująca świat (właściwa ontologia) albo sprawozdania (opisy), dla których ontologia jest metamodelem (ontologia tu, to metadane sprawozdań). Tak więc możemy powiedzieć, że gromadzenie wiedzy wymaga dziedzinowego (specyficznego dla dziedziny) modelu pojęciowego: ontologii. Na tej podstawie można zbudować model struktury danych. Pokazano, że obecnie najbardziej adekwatny do opisów byłby model dokumentowy, gdyż opisy obiektów będą skomplikowanymi agregatami o zmieniającej się w czasie strukturze, zależnej od typu obiektu, ale też odwzorowującej wiedzę o nim. Predykaty są znacznie prostsze i przechowywanie ich w postaci samych prostych metadanych wydaje się wystarczające. Całość tworzy sieć, w której węzły są obiektami a krawędzie faktami.

Biorąc pod uwagę ogromne ilości zbieranych danych oraz to, że “nie można sie pomylić”, modele SQL/RDBMS, z ich sztywnością i brakiem redundancji, wydają się nieadekwatne. Ontologie jako wiedza o istocie świata (np. w systemach sztucznej inteligencji) bardzo dobrze pasują do baz grafowych. Ogromne ilości danych sprawozdawczych doskonale pasują do baz dokumentowych. Wyzwaniem w projektach tego typu jest zbudowanie dziedzinowej ontologii, a potem zaprojektowanie agregatów (dokumentów) przechowujących dane sprawozdawcze. Przykładem takich agregatów są np. opisy zmieniających się produktów jako obiektów oraz faktury jako fakty dokonania transakcji ich sprzedaży (co, kto komu, za ile, kiedy). Zdanie “Jan sprzedał Krzysztofowi rower” to wiedza o tym, że pewien fakt (moment dokonania transakcji) połączył trzy obiekty: sprzedawcę, nabywcę, sprzedany produkt.

Dalsze prace

Dalsze prace prowadzone są w kierunku stworzenia ogólnej uniwersalnej metody analizy i projektowania systemów zarządzania informacją na bazie ontologii i struktur dokumentowych i wdrażanie ich w systemach zarzadzania informacją zarówno ERP jak AI.

Dodatek

Pojęcia klasy obiektów, klasyfikatora, wartości a także pojęcia reprezentującego obiekty, które mogę reprezentować wartość czego to zbiory, definicje elementów i elementy. Z elementów zbioru, za pomocą predykatów, mozna budować “zdania prawdziwe” czyli opisy. Poniżej ciekawa prezentacja o teorii zbiorów i rachunku predykatów. Bardzo ważna dla zrozumienia tego czym tak na prawde jest analiza pojęciowa.

Źródła

[zotpressInTextBib style=”apa” sort=”ASC”]

Wprowadzenie

Tym razem krótka recenzja pewnej książki z roku 2006, a raczej jej polecenie każdemu projektantowi i architektowi dzisiaj. Na końcu polecam także kolejną nowszą pozycję jako uzupełnienie. Adresatami tej recenzji są głównie analitycy i projektanci, jednak adresuję ten wpis także do developerów, zakładam że dla nich nie jest to “coś nowego”, ale być może mają jakieś rady dla projektantów.

Warto także podkreślić, że pomiędzy OOP a OOAD jest coraz większa różnica i podział na role: analiza i projektowanie oraz implementacja, a także postępująca separacja tych ról, stają się standardem w inżynierii oprogramowania [zotpressInText item=”{5085975:NZCQDD79}”]:

Programming is not solely about constructing software, programming is about designing software.

[zotpressInText item=”{5085975:NZCQDD79}”]

Kolejna warta zwrócenia uwagi rzecz: projektowanie integracji systemów w organizacji to nic innego model systemu zorientowany na interfejsy (patrz wcześniejszy wpis: Integracja systemów ERP jako źródło przewagi rynkowe).

Zanim jednak wczytacie się Państwo z detale, polecam krótki referat Martina Fowlera z 2015 roku:

Making Architecture Matter – Martin Fowler Keynote

Recenzja

Interface-Ofriented Design [zotpressInText item=”{5085975:DQ85BDLN}”], to książka o architekturze i jej projektowaniu. We wstępie autor pisze (oryg):

[zotpressInText item=”{5085975:DQ85BDLN}”]

Autor, na wielu przykładach pokazuje jak można projektować (tworzyć) oprogramowanie budując je ze współpracujących komponentów.

Wiele się mówi o programowaniu obiektowym a mało o projektowaniu zorientowanym na komponenty (moduły). Ważna rzecz: projektowanie zorientowane na interfejsy koncentruje się na komponentach i ich interfejsach, komponenty te mogą, ale nie muszą, być implementowane za pomocą języków obiektowych. Projekty, które skupiają się na komponentach i ich interfejsach mają ogromną zaletę: precyzyjnie opisują co ma program robić a jednocześnie nie narzucają narzędzia implementacji.

Kolejna rzecz to fakt, że obecnie znacznie bardziej niż w czasach gdy książka była pisana (ukazała się w 2006 roku), nabiera znaczenia rozproszona architektura: realnie nie ma już monolitów, mamy integracje systemów między partnerami handlowymi, z rejestrami publicznymi, między lokalnymi i chmurowymi infrastrukturami. Rozproszone przetwarzanie to architektury zorientowane na usługi, które kładą szczególny nacisk na interfejsy.

Interfejsy mogą być zorientowane na procedury (takie jak zdalne wywołania funkcji) lub na dokumenty (serwisy internetowe i integracje z protokołem RESTful API). Autor opisuje także wzorce i metody projektowania bazujące na luźnych powiązaniach, które są kluczowe dla budowania systemów rozproszonych. Więcej o interfejsach zorientowanych na dokumenty w moich projektach,

Ważna rzecz, na którą autor także zwraca szczególną uwagę: dziedziczenie jest często trudną do osiągnięcia techniką, jest to także często jedna z najbardziej nadużywanych cech języków obiektowych. Nacisk autora na interfejsy może wydawać się nieco ekstremalny, jednak (świeże w 2006 roku) spojrzenie na projektowanie architektury zorientowane na komponenty i ich odpowiedzialność, daje zaskakująco dobre efekty, a pamiętajmy, że generalnie liczy się cykl życia aplikacji (patrz także artykuł Znaczenie na cykl życia…) czyli koszty jej utrzymania i rozwoju, a nie samo jej wytworzenie. Warto pamiętać, że dziedziczenie z zasady łamie zasadę hermetyzacji i zalecane jest zastępowane go stosowaniem szablonów lub po prostu rezygnuje się z tej techniki na rzecz typów danych i kompozycji.

Podsumowując: Kluczowym przesłaniem autora jest “odejście” od “programowania obiektowego” (orientacja kodu na dziedziczenie oraz łączenie funkcji i danych w obiekty, OOP) na rzecz “projektowania zorientowanego na niezależne, luźno powiązane komponenty” (polimorfizm i hermetyzacja), cechującego się pełną separacją komponentów, luźnymi powiązaniami (tylko wywołania operacji) i pojedynczą odpowiedzialnością (OOAD).

Autor zwraca uwagę na sprawdzone wzorce, kluczowe: to fabryka (zwana także metodą wytwórczą, jest to separacja metod tworzenia obiektów od ich utrwalania), adapter (separacja współpracujących komponentów o niedopasowanych interfejsach). Co do zasady też (wzorce) separujemy przetwarzanie danych od ich samych (wzorzec repozytorium [zotpressInText item=”{5085975:ZIIDU6A9},{5085975:NVN9AR49},{5085975:ZBEHPADF},{5085975:8P6M5STE}”]). Dzisiaj dominujące są więc mikro serwisy i mikro aplikacje, natomiast łączenie danych i metod je przetwarzających w jednej klasie to antywzorzec.

Początek lat 2000 to nie tylko manifest Agile, to także już kilka lat po nim, nawoływanie sygnatariuszy Agile do porządku w inżynierii oprogramowania [zotpressInText item=”{5085975:P5PE3C3R}”]. Poza omawianą tu książką pojawiły się, w tamtym okresie, między innymi opis budowy komponentowej architektury [zotpressInText item=”{5085975:NSJBENX9}”], opis projektowania zorientowanego na odpowiedzialność komponentów [zotpressInText item=”{5085975:VNQDV6CQ}”].

Autor zwraca także szczególną uwagę na dokumentowe modele budowy interfejsów i integracji. Dokumentowe czyli zorientowane na przekazywanie między komponentami całych agregatów danych (zwanych dokumentami) zamiast wyników działania poszczególnych funkcji. Znakomicie upraszcza to architekturę, powoduje mniejsze uzależnienia, w konsekwencji cykl życia takiego systemu jest znacznie tańszy. O tym aspekcie architektury integracji pisał także znany autor Martin Fowfer [zotpressInText item=”{5085975:3BRMMXGI}”].

Zachęcam do lektury tej książki, porządkuje wiedzę, być może wielu z Was znajdzie coś nowego. Od siebie powiem, że podejście takie stosuję od czasów lektury Systemów zorientowanych komponentowe Souzy, czyli od ponad 15 lat…

A architekturze

Doskonałym i aktualnym uzupełnieniem tej książki jest napisana później Czysta architektura [zotpressInText item=”{5085975:QEGGUWKX}”]:

Dobrzy architekci ostrożnie oddzielają szczegóły od reguł biznesowych, robiąc to tak dokładnie, że reguły te nie mają żadnej wiedzy o szczegółach i w żaden sposób od nich nie zależą. Dobrzy architekci tak projektują reguły systemu, żeby wszystkie decyzje dotyczące szczegółów można było podejmować tak późno, jak to tylko możliwe.

Przy tej okazji polecam także prezentację opartą na treści książki [zotpressInText item=”{5085975:IWBHW8XL}”], szczególnie część o interfejsach, głębokości i płytkości klas: A Philosophy of Software Design | John Ousterhout | Talks at Google

A Philosophy of Software Design | John Ousterhout | Talks at Google

OOP i OOAD czyli co dalej?

[2023-01-07]

Od wielu lat obserwuję rynek i projekty z zakresu inżynierii oprogramowania. Pojęcia OOP (programowanie obiektowe) oraz OOAD (analiza obiektowa i projektowanie) oddalają się od siebie. Techniki organizacji kodu rodem z C++/Java (mają współny rodowód) zdeterminowały pojmowanie pojęcia “programowania obiektowego”. Są to ciężkie metody pracy, oparte na starych wodospadowych założeniach (monolityczna architektura oparta na relacyjnym modelu danych) sprawdzają się tam, gdzie zmienność wymagań jest mała.

C++ znajduje zastosowanie w tworzeniu systemów operacyjnych (np. Windows XP czy Vista), a także podczas budowy aplikacji desktopowych (pakietu Office bądź produktów Adobe). Z wykorzystaniem C++ można spotkać się także podczas budowy baz danych oraz serwerów. Popularność C++ zdecydowanie nie słabnie wśród twórców gier. Sprawdza się świetnie nie tylko podczas produkcji prostych projektów 2D, ale także gier typu AAA.

Język Java stosuje się przede wszystkim w backendowej części budowy internetowych aplikacji. Wykorzystuje się go także w projektowaniu aplikacji desktopowych, korporacyjnych, a nawet całych serwerów aplikacji. Język Java stanowi podstawę działania aplikacji mobilnych oraz gier dla systemu Android. Java stosowana jest także w systemach bankowych i giełdowych.

źr.: https://work4.dev/blog/28/Czy-C-i-Java-sa-do-siebie-podobne.html

Systemy określane jako “biznesowe” to zupełnie inna klasa oprogramowania, to aplikacje budowane w oparciu o reguły biznesowe i odrębne dokumenty. Jedne i drugie szybko sią zmieniają, stosowaniu tu metod i narzędzi adekwatnych do budowy gier i systemów operacyjnych (one się zmieniają rzadko i nie służą do zarządzania danymi) prowadzi to do powstawania bardzo kosztownych w utrzymaniu i rozwoju systemów. Dlatego równolegle rozwijają się takie języki jak JavaScript, Ruby, PHP, Pyton, HTML czy Perl.

Analiza i projektowanie “obiektowe”, pierwotnie oparte na idei hermetyzacji, luźnych powiązaniach i interfejsach, tak na prawdę sprowadza się do poprzedzania kodowania projektowaniem architektury, a to “tylko” komponenty i ich współpraca, bez wnikania w technologie ich powstania, tym bardziej, że wiele z nich (komponenty) można kupić jako COTS (ang. Commercial off-the-shelf, gotowe komponenty z półki) bez wiedzy o ich wewnętrznej strukturze (czyli hermetyzacja).

Developerzy często posługują sie pojęciem klasy mając na myśli konstrukcje znane im z C++ czy Java. Poniekąd słusznie, bo faktycznie ich używają tworząc implementacją (pisząc kod). Na etapie analiz i projektowania detale kodu nie mają znaczenia, liczy się realizowana logika i architektura.

A gdzie tu UML? Mityczne generowanie kodu z UML nie wyszło poza mury akademickich entuzjastów tego pomysłu. Więc gdzie? Po oczyszczeniu z nadmiaru (redukcja UML), jest to doskonałe narzędzie do modelowania systemów i tworzenia sformalizowanych schematów blokowych. Czym jest klasa w UML? Wszystkim, a to co jest klasą w C++/Java to malutka część tego “wszystkiego”. Czy na etapie projektowania (model PIM) mamy na myśli klasy w rozumieniu konstrukcji kodu C++/Java? Nie, na tym etapie mamy komponenty (ale w UML wszystko jest klasą, komponent też), w zasadzie czarne skrzynki z interfejsami, które trzeba (wystarczy) opisać. To co opisze projektant zależy od niego: tam gdzie uzna, że daje swobodę deweloperowi poprzestanie na komponentach, ich interfejsach i procedurach (algorytmach) realizowanych przez te komponenty. Tam gdzie uzna, że to ważne, narzuca wybrane szczegóły (patrz Kto jest programistą).

Dlatego od bardzo dawna (patrz opisywana wyżej książka) mówi się i pisze, że projektowanie systemów to właśnie projektowanie zorientowane na komponenty i ich interfejsy. Implementacja jest zawsze wtórna. A to co można nadal spotkać w wielu podręcznikach i analizach pod nazwą “diagram klas”, to często poprawne i zarazem bezwartościowe diagramy w UML (Patrz UML dla programistów Java).

Na zakończenie ciekawa prezentacja: najpierw projektowanie, kod na końcu.

Design First APIs and Domain-Driven Design – Ljubica Lazarevic – DDD Europe 2022

Źródła

[zotpressInTextBib style=”apa” sortby=”author” sort=”ASC” cite=”yes”]

Artykuł ma dwie części. Pierwsza część jest adresowana do kadr zarządczych, cały artykuł (obie części) do osób zajmujących się projektowaniem rozwiązań.

Wstęp

Mamy ogólnoświatową sieć Internet, aplikacje lokalne i w chmurze, aplikacje naszych kontrahentów i aplikacje centralnych urzędów. Wszystkie one współpracują i wymieniają dane, czyli są zintegrowane. Dlatego integracja stała się cechą każdego systemu informatycznego.

Wyjątkowo na początku (poniżej) umieszczam cały ten ciekawy referat, można bo pominąć i czytać dalej, jednak jeżeli ktoś chce poznać przewidywania z roku 2016 i ma czas, polecam (teraz lub później):

The Future of Software Engineering ? Mary Poppendieck ? GOTO 2016

Obecnie kluczowym pytaniem jest: Jak zintegrować, a nie: Czy zintegrować.

Pogodzenie się z tym, że świat systemó ERP już nigdy nie będzie tak prosty jak w czasach mainframe’ów, czyli jednej centralnej aplikacji, jest nieuniknione.

Czym jest obecnie integracja? To wymiana danych a nie ich współdzielenie: dane z urzędem wymieniamy, dane z kontrahentem wymieniamy, nie współdzielimy żadnych danych z tymi podmiotami, każdy ma swoje własne, bezpieczne bazy danych, i to wszystko ładnie działa! Idea zbudowania wszystkich funkcjonalności jako zintegrowanej aplikacji na jednej współdzielonej bazie danych w czasach obecnych jest utopią. Taką samą jak hipotetyczna centralna baza danych dla wszystkich sklepów internetowych, firm kurierskich i banków, a one są jednak zintegrowane: one wymieniają dane a nie współdzielą!

ERP to (ang.) Enterprise Resource Planning czyli Planowanie Zasobów Przedsiębiorstwa. To system wykorzystywany przez firmy do zarządzania i integrowania ważnych elementów ich działalności. Ale kto powiedział, że to ma być monolit od jednego producenta?

Nadal spotykam pejoratywne określenia “system pointegrowany” jako krytykę budowy systemu ERP z komponentów i integracji jako wymiany danych. Autor tego określenia najprawdopodobniej nadal żyje w świecie mainframe.

Chociaż dostawcy systemów ERP oferują aplikacje dla przedsiębiorstw i twierdzą, że ich zintegrowany system jest najlepszym rozwiązaniem, wszystkie moduły w jednym systemie ERP rzadko kiedy są najlepsze z najlepszych.

https://www.gartner.com/en/information-technology/glossary/best-of-breed
(more…)

Architektura reprezentuje ważną decyzję projektową, która wpływa na kształt systemu, przy czym waga decyzji mierzona jest kosztami zmian, które wprowadza.

— Grady Booch

Jeśli myślisz, że dobra architektura jest droga, spróbuj złej

Foote, B., & Yoder, J. (2003). 
Big Ball of Mud . 
https://www.researchgate.net/publication/2938621_Big_Ball_of_Mud

Wprowadzenie

Tym razem troszkę cięższy kaliber, czyli dywagacje o tym co powszechnie jest określane jako metody obiektowe i o tym skąd “konflikty i nieporozumienia” między programistami i analitykami projektantami.?*?

Literatura przedmiotu zawiera wiele różnych sposobów grupowania metod programowania w paradygmaty. Autorzy z reguły skupiają się na tym, czym są programy rozumiane jako zorganizowana lista poleceń dla maszyny. Mogą to być sekwencje prostych poleceń, mogą to być wykonywane wg. określonego scenariusza funkcje.  Typowym przykładem takiego grupowania jest np. wykład (tu jego spis treści) dostępny w sieci Internet:

Wstęp
1.1 Przykład pierwszy: programowanie imperatywne
1.2 Przykład drugi: programowanie obiektowe
1.3 Przykład trzeci: programowanie funkcyjne
1.4 Przykład czwarty: programowanie w logice (programowanie logiczne) ?1?

Wykład ten, z uwagi na to, że  pochodzi ze stron mimów.edu .pl (Uniwersytet Warszawski, Wydział Informatyki) w moich oczach, po lekturze kilkunastu podobnych,  jest reprezentatywnym dla wielu środowisk akademickich podejściem.

Problemem rynku IT od bardzo dawna jest tak zwany Kryzys Oprogramowania (Software crisis). jego źródłem jest stale rosnąca złożoność kodu aplikacji. Pierwsze komputery wykonywały jedynie pojedyncze złożone obliczenia, co skutkowało powstaniem kodu o objętości kilkuset linii kodu, rzadko więcej. Jednak od czasu gdy oprogramowanie, a konkretnie komputer, stało się narzędziem pracy poza laboratoriami: w urzędach, instytucjach czy firmach, jego złożoność zaczęła lawinowo rosnąć. Do tego wolumeny danych to już terabajty i ich struktury to wielokrotnie zagnieżdżone dokumenty i formularze. W efekcie programy z kilkuset linii doszły do setek ich tysięcy, nie raz milionów linii kodu. Jest to coś, czego umysł, pamięć i wyobraźnia człowieka nie są w stanie ogarnąć.

Dlatego prawie od samego początku inżynierii oprogramowania mówimy o “architekturze oprogramowania”. Program komputerowy to procedury i algorytmy. Jeżeli jest ich kilkadziesiąt, mozna je grupować np. w podprogramy. Jednak jeżeli są ich setki i tysiące pojawia się konieczność grupowania ich w nadrzędne grupy. Początkowo kod grupowany był w funkcje,, jednak szybko sie okazało, że lista setek funkcji jest nie mniej kłopotliwa niż wcześniej setki linii kodu.

Okazało się, że lepszym rozwiązaniem jest tematyczne, dziedzinowe grupowanie linii kodu w komponenty i realizowanie funkcjonalności oprogramowania jako scenariuszy ich użycia. Tak narodził się tak zwany paradygmat obiektowy: system składa się z komunikujących się hermetycznych obiektów (dziedziczenie i łączenie funkcji i danych w obiekty to cechy języków programowania a nie paradygmat obiektowy, patrz prezentacje na końcu artykułu).

W tym artykule postaram się wyjaśnić na czym to polega.

Programowanie strukturalne

Jest to paradygmat programowania opierający się na podziale kodu źródłowego programu na procedury i hierarchicznie ułożone bloki z wykorzystaniem struktur kontrolnych w postaci instrukcji wyboru i pętli. Rozwijał się w opozycji do programowania wykorzystującego proste instrukcje warunkowe i skoki. Programowanie strukturalne zwiększa czytelność kodu i ułatwia analizę programów, co stanowi znaczącą poprawę w stosunku do trudnego w utrzymaniu ?spaghetti code? często wynikającego z użycia instrukcji “go to”. Nadal jest to jednak długa lista silnie powiązanych procedur.

Metody strukturalne analizy i projektowania bazują na uznaniu, że oprogramowanie to stos funkcji operujących na bazach (składach) danych. Innymi słowy podstawowe założenie to istnienie odrębnych bytów jakimi są baza danych oraz funkcje, które na tych danych wykonują operacje. W metodach strukturalnych tworzy dwa się rodzaje modeli: model procesu przetwarzania i model struktury danych. Pierwszy wykorzystuje notację DFD (Data Flow Diagram, np. notacja Gane?a- Sarsona) a drugi notacja ERD (Entity Relationship Diagram, np. notacja Martina) do modelowania struktur relacyjnych baz danych.

Rysunek 1 Diagram DFD w notacji  Gene’a – Sarsona

Struktura aplikacji w postaci tak zwanej ?czarnej skrzynki? została pokazana na Rysunku 1. W metodach strukturalnych, na poziomie opisu architektury, aplikacja ?dzielona jest? na podfunkcje (patrz Rysunek 2.).

Rysunek 2 Dekompozycja funkcji

Starsze podręczniki informatyki i programowania powołują się na ?zasadę?:  algorytmy + struktury danych = oprogramowanie (aplikacje). Kod zawierający funkcje jest z reguły dzielony jest na części zwane ?podprogram?, jednak niezależnie od tego jak jest zorganizowany, jest to zwarty i niepodzielny system funkcji i algorytmów, który zapisuje i odczytuje dane ze współdzielonego ?magazynu danych?. Najczęściej tym magazynem jest relacyjnie zorganizowana baza danych?2?, czyli system powiązanych tablic, w którym usuwa się redundancje i tworzy trwałe związki logiczne między tak zorganizowanymi danymi.

Modelowania struktur relacyjnych baz danych (notacja ERD, Entity Relationship Diagram, tu notacja Martina)

Architektura taka nie sprawia większych problemów do momentu gdy aplikacja nie zaczyna się rozrastać i nie pojawia się potrzeba wprowadzania kolejnych nowych lub zmienionych elementów mechanizmu jej działania. Wtedy każda ingerencja w tak zorganizowaną architekturę dotyczy prawie zawsze całej aplikacji. Stabilne kiedyś otoczenie (środowisko użytkowania tych aplikacji) pozwalało na projektowanie oprogramowania, od którego nikt nie oczekiwał, że pozwoli na łatwe i szybkie wprowadzanie zmian. Po drugie, tworzeniem oprogramowania zajmowały się małe zespoły programistów, zaś logika przetwarzania polegała raczej na realizowaniu małej liczby typów operacji na wielkich ilościach danych, to były głownie projekty inżynierskie a nie badawcze. Zamawiający (tak zwany dzisiaj ?biznes?) musiał jedynie spisać dane i operacje oraz wzory (formuły) z jakich użyciem były one przeliczane.

Zmiana paradygmatu

Rosnąca złożoność oprogramowania wymusiła szukanie nowych rozwiązań. Początkowo dzielono kod aplikacji na separowane części – moduły, jednak nadal stanowiły one jedną całość z powodu pracy z danymi w postaci jednej zwartej struktury, jaką jest współdzielona relacyjna baza danych. Fakt ten często jest postrzegany jako zaleta:  wskazuje się na brak redundancji, łatwy sposób uzyskania spójności danych, współdzielenie jako łatwą integrację. Problem w tym, że duże aplikacje operują w wielu kontekstach, co powoduje, że współdzielona baza danych o ustalonej strukturze, musi stanowić kompromis. Np. dane stanowiące zapis kolejnych zakupów amortyzowanych środków trwałych mają inną strukturę i logikę wzajemnych powiązań, niż te same dane w kontekście złożonych konstrukcji mechanicznych jakimi są te środki trwałe. Innym przykładem obrazującym kwestie kontekstowości jest przykład na blogu Martina Fowlera.?3?

Rysunek 3 Granice kontekstu i zmiana  perspektywy pojęć ?3?.

Jak widać na Rysunku 3., mamy  tu dwa konteksty i redundancje (pojęcia Customer i  Produkt powielone po obu stronach: w obu dziedzinach). Powyższe powinno być podstawą do podziału projektu na dwa odrębne komponenty z własnymi (nie współdzielonymi) danymi. Jak widać każdy komponent operuje pojęciami Customer i Produkt,  jednak inny jest ich kontekst. Inne cechy dziedzinowe tych pojęć nie są  (nie powinny być) współdzieloną informacją w jednej bazie danych, oba komponenty będą miały swoje odrębne modele danych, zapewne o różniącej strukturze. Powód pierwszy to inne związki pojęciowe i być może nawet inne definicje pojęć. Produkt w kontekście sprzedaży ma nazwę, cenę, dostępność itp. Produkt w kontekście uszkodzeń ma numer seryjny, wersję, użytkownika itp. Inne będą reguły biznesowe w każdym komponencie. Drugi powód to łatwa dostępność  na rynku specjalizowanych produktów typu CRM i TicketXXX, szukanie (tworzenie) jednego ?pakietu zintegrowanego? będzie bardzo trudne, bo kontekstów sprzedaży a potem obsługi uszkodzeń czy reklamacji, jako pary, będą tysiące wariantów. Wytworzenie (zakup) osobno, i integracja dwóch odpowiednio dobranych komponentów (aplikacji), będą znacznie łatwiejsze.

Powoli zaczęły swego czasu powstawać aplikacje dziedzinowe, jednak nadal wewnętrznie miały one opisane wyżej wady współdzielenia danych w jednej bazie. Do tego ich integracja polegała na wzajemnym sięganiu do danych co stanowiło bardzo duży problem z powodu różnych struktur tych danych, zaś wymiana jednej z nich na inną wymagała opracowania od nowa całej koncepcji integracji współdzielonych danych co pokazano na Rysunku 4.

Rysunek 4 Integracja aplikacji strukturalnych

Obiektowy paradygmat

Co ciekawe powstanie metod obiektowych nie było szukaniem sposobu usunięcia wad systemów strukturalnych. Pierwsze obiektowe narzędzia powstały już w latach sześćdziesiątych XX w. narzędzia i programy strukturalne także powstają do tej pory.

Do obecnej popularności metod obiektowych doprowadziły dwie ścieżki: problem rosnącej złożoności kodu aplikacji oraz potrzeba utrzymania zrozumieniu ?tego czym jest ta aplikacja? po stronie zamawiającego.

Proces, powszechnie zwany “zbieraniem wymagań”, staje się coraz bardziej skomplikowany i ryzykowny, w miarę jak rośnie złożoność tych systemów.

Wymagania na oprogramowanie naliczające wynagrodzenia tysiącom pracowników to ?jeden wzór? na naliczenie wynagrodzenia oraz pewna liczba cech jakościowych takich jak wydajność czy dostępność. Jednak opisanie tą metodą “jednej” aplikacji, operującej dziesiątkami dokumentów o różnych strukturach i ogromnej ilości zależności między nimi, z pomocą ?listy cech? zaczyna przybierać postać setek, a nie raz tysięcy, linii i danych w tabelach. Przy takiej ilości “wymagań” praktycznie żaden sposób ich organizacji nie wprowadza wartości dodanej, zaś ich liczba praktycznie nie pozwala na kontrolę kompletności i niesprzeczności.

Popatrzmy na komentarz autora wykładu?1? do obiektowego programowania:

W programowaniu obiektowym program to zbiór porozumiewających się ze sobą obiektów, czyli jednostek zawierających pewne dane i umiejących wykonywać na nich pewne operacje
– Ważną cechą jest tu powiązanie danych (czyli stanu) z operacjami na nich (czyli poleceniami) w całość, stanowiącą odrębną jednostkę: obiekt.
– Cechą nie mniej ważną jest mechanizm dziedziczenia, czyli możliwość definiowania nowych, bardziej złożonych obiektów, na bazie obiektów już istniejących.
Zwolennicy programowania obiektowego uważają, że ten paradygmat dobrze odzwierciedla sposób, w jaki ludzie myślą o świecie
– Nawet jeśli pogląd ten uznamy za przejaw pewnej egzaltacji, to niewątpliwie programowanie obiektowe zdobyło ogromną popularność i wypada je uznać za paradygmat obecnie dominujący.

W cytowanym tekście widać stereotypowe podejście autora:

“metody obiektowe tworzenia oprogramowania, opierają się na wyróżnianiu w tworzonym oprogramowaniu dwóch rodzajów składowych: pasywnych odzwierciedlających fakt przechowywania w systemie pewnych danych oraz składowych aktywnych odzwierciedlających fakt wykonywania w systemie pewnych operacji. Metody obiektowe wyróżniają w systemie składowe, które łączą w sobie możliwość przechowywania danych oraz wykonywania operacji.” (źr. wikipedia).

Schematycznie można to przedstawić tak:

Podejście, które nazwę programistycznym, to uznanie, że trzeba podzielić dużą aplikację na mniejsze odrębne komponenty, z których każdy ma “swoje funkcje i dane”.  Tu także podkreślana jest kwestia re-użycia kodu w postaci tak zwanego dziedziczenia jako “mechanizmu definiowania nowych, bardziej złożonych obiektów, na bazie obiektów już istniejących” .

Zupełnie inną drogą jest podejście oparte na uznaniu, że świat rzeczywisty to określony mechanizm, który da się odwzorować jako pewna abstrakcja za pomocą kodu (jego struktury).  Tu struktura kodu jest konsekwencją struktury tego obszaru “świata rzeczywistego”, którego dotyczy tworzone oprogramowanie (o czym już na swoim blogu nie raz pisałem).

Skutek jest “taki sam”: program stworzony zgodnie z obiektowym paradygmatem będzie się owszem składał z klas obiektów, które komunikują się wzajemnie.  Jednak nie jest to podejście zorientowane na dzielenie dużej aplikacji na podprogramy traktujące obiekty jako “jakieś” komponenty zawierające w sobie kod funkcji i dane na jakich one operują. Podejście zorientowane na modelowanie  “świata rzeczywistego” zaowocuje obiektami stanowiącymi abstrakcje (modele) elementów świata rzeczywistego. Struktura takiego kodu w obu przypadkach będzie “obiektowa” ale jej sens nie raz jest skrajnie inny np. obiekt faktura będzie zawierał dane o sprzedaży ale nie będzie miał operacji “nowa faktura”, bo faktury nie tworzą nowych faktur (ani nie niosą informacji o tym jak powstawały). Faktury będą tworzone przez inny obiekt np. Twórca faktur (albo jak w niektórych wzorcach: fabryka faktur).?4?

Od lat sześćdziesiątych prowadzone są prace nad metodami obiektowymi w inżynierii oprogramowania, powstaje języka SIMULA w 1967 roku. W 1968 roku opublikowano pierwsze oficjalne wydanie Ogólnej Teorii Systemów Ludwiga von Bertalanffy’ego (publikacje na jej temat pojawiały się od już 1964 roku).  Teoria systemów mówi, że “system to współpracujące obiekty”, język SIMULA powstał do tworzenia (programów) symulacji obiektów świata rzeczywistego.

Oba wskazane podejścia są znane od lat, jednak podejście “inżynierskie” (dzielenie dużego kodu na małe kawałki) dominuje, nie tylko jak widać w systemie kształcenia.

Ogólna teoria systemów traktuje wszystko jak “system” (współpracujące obiekty). Z zewnątrz system to obiekt reagujący na bodźce. Reakcja ta może być opisana mechanizmem jej powstawania, to wewnętrzna struktura systemu. Jeżeli uznać, że oprogramowanie (i komputer) zastępuje określoną rzeczywistość (np. mechaniczny zegar zastąpiony programem wykonywanym w komputerze) to można przyjąć, że komputer to maszyna abstrakcyjna, jej implementacja realizuje konkretne systemy i (lub) ich komponenty?5?.

Nie chodzi więc o to by podzielić oprogramowanie na “składowe, które łączą w sobie możliwość przechowywania danych oraz wykonywania operacji”. Chodzi o to by mechanizm, o dowiedzionej poprawności, zaimplementować w określonej wybranej technologii.

Chodzi też o to by nie udawać, że programowanie jako “podzielone na obiekty” partie kodu, nadal korzystające z jednej wspólnej bazy danych, różni się czymkolwiek od “strukturalnego kodu”. Chodzi o to by kod programu faktycznie implementował określony (zbadany i opisany) mechanizm.

Tak więc “obiektowy paradygmat” to nie “nowe programowanie”, to architektura kodu: “obiektowa” architektura???.

Proces projektowania oprogramowania, idąc tropem analizy systemowej i opisania mechanizmu działania “tego czegoś”, zaczyna się już na etapie analizy. Programista implementuje model a nie “wymyśla program”. Oczywiście pod warunkiem, że mamy tu na myśli analizę obiektową i projektowanie systemu a nie “jakiś podział kodu na klasy”.

Poniżej komponentowa (obiektowa) struktura aplikacji i diagramy UML jakimi jest wyrażana:

Na zakończenie jeden z moich ulubionych cytatów na temat analizy i projektowania obiektowego:

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

Polecam wysłuchanie referatu na temat roli architeltury:

A Philosophy of Software Design | John Ousterhout | Talks at Google

Na temat tego, że UML jest lepszy od odręcznych szkiców:

Oraz referatu na temat zalet projektowania poprzedzającego kodowanie:

Oraz kolejnego referatu o architekturze i dekompozycji:


  1. ?*?
    Artykuł został opublikowany w materiałach pokonferencyjnych: 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 autorów przywołuje tu pojęcie komponentów a nie obiektów. Komponentem jest tu każdy samodzielny, komunikujący się z otoczeniem, obiekt niezależnie od wielkości i stopnia złożoności.

Źródła:

  1. 1.
    Paradygmaty programowania/Wykład 1: Co to jest paradygmat programowania? – 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.
    Relacyjne bazy danych -podstawy. SQLpedia. http://www.sqlpedia.pl/relacyjne-bazy-danych-pojecia-podstawowe/. Published April 16, 2013. Accessed July 17, 2017.
  3. 3.
    Fowler M. bliki: BoundedContext. martinfowler.com. https://martinfowler.com/bliki/BoundedContext.html. Published January 15, 2014. Accessed July 16, 2017.
  4. 4.
    Żeliński J. Analiza biznesowa. Praktyczne modelowanie organizacji. onepress.pl. http://onepress.pl/view/2239k/sfomod.htm. Accessed July 16, 2017.
  5. 5.
    Filozofia matematyki i informatyki. Księgarnia Internetowa PWN. https://ksiegarnia.pwn.pl/Filozofia-matematyki-i-informatyki,84899525,p.html. Accessed July 17, 2017.
  6. 6.
    Martin Fowler, Analysis Patterns, 1997.

Dodatek