W dwóch ubiegłorocznych artykułach pisałem o modelach pojęciowych oraz o związkach w UML. Opisałem je od strony notacyjnej. Dzisiaj o ich zastosowaniu.
Generalnie zagadnienia modeli pojęciowych, abstrakcji i metamodeli oraz związków między nimi są dość trudne (wbrew pozorom, większość ludzi ma problem z abstrakcyjnym myśleniem), jako narzędzia są bardzo przydatne w analizie i projektowaniu.
Rzecz w tym, że systemy analizowane istnieją, co znaczy ni mniej ni więcej tylko to, że „są dobre bo są i działają”. Gorzej jest gdy system, nie raz nietrywialny, jest na etapie projektowania. Wtedy o tym jest „dobry” przekonamy się dopiero gdy go stworzymy (lub podejmiemy taką próbę). Odkrycie, że jednak nie jest dobry bywa kosztowne.
Najczęstszymi wadami projektów systemów są wewnętrzna niespójność, niekompletność i wewnętrzne sprzeczności. Jak ich uniknąć na etapie projektowania? Jest rada: projektować od ogółu do szczegółu, stale przestrzegać śladowania, pracować na abstrakcjach i metamodelach. To pozwoli zapanować nad złożonością projektu (systemu). Nie da się tego robić „ręcznie” dlatego bez dobrego oprogramowania CASE takie projekty są raczej skazane na niepowodzenie lub znaczne dodatkowe koszty.
Przykład
Na prostym przykładzie pokażę jak i kiedy używać różnych, bardzo ważnych związków i poziomów abstrakcji. Przykładem będzie pies i kojec. Najpierw model pojęciowy, który zagwarantuje jednoznaczność całości oraz zrozumienie problemu.
Bardzo często popełnianym błędem jest „przeciążanie” diagramów i (lub) mieszanie kontekstów. Polega to na mieszaniu na jednym diagramie modeli pojęciowych i strukturalnych (pisałem też o tym w artykule o diagramach klas). Model pojęciowy to słownik pojęć i zależności pomiędzy pojęciami (w notacji SBVR są to wyłącznie fakty łączące te pojęcia w jeden kontekst). W tym przykładzie mamy taki oto model:
Tworzenie modelu pojęciowego ma jedno kluczowe zadanie: zagwarantować spójność i jednoznaczność nazewnictwa w reszcie projektu. A nazwy dostają: klasy, atrybuty, operacje, aktorzy, wartości atrybutów klas, obiekty, itp.. Utrzymanie tu porządku, wbrew pozorom, nie jest łatwe. Na modelach pojęciowych stosujemy wyłącznie dwa związki: dziedziczenie czyli związek uogólnienia/specjalizacji (wskazuje typy) oraz asocjacje czyli nazwane związki między pojęciami. Tak więc typy ras to owczarek, pudel, ratler zaś pomiędzy psem a rasą jest taki związek, że nazwa rasy opisuje pewne cechy psa. Mamy także typy legowisk (buda, kojec) i związek psa z legowiskiem. Każda z tych nazw (pojęć) powinna mieć ścisłą definicję (w dokumentacji osobna tabela, zestawienie).
Teraz pora na projekt.
Projekt jest prosty wiec jego elementy zmieściły się na jednym diagramie. Tu mamy diagram obiektów (można na nim umieszczać także klasy). Większe projekty to większa liczba diagramów bardziej specjalizowanych.
Tak więc metamodel to klasyfikatory i związki między nimi. Klasyfkator (klasa) zastępuje np. setki psów i ich kojców. Metamodel pokazuje w postaci uogólnionej związki między obiektami naszego świata, tu pokazano, że zwierze korzysta z kojca. Jak widać, użyto nazwy kojec a nie legowisko, dlaczego? Bo z jakiegoś powodu wiemy, że to jednak kojec i użyto tej nazwy do nazwania klasy. Konkretna sytuacja to pies rasy ratler korzystający z kojca w postaci poduszki (u konkretnych Kowalskich). Burek (tak sie wabi pies) to ratler, jest instancją klasy zwierzę. Poduszka u Kowalskich to instancja kojca. Rynkowy produkt Kojec ALFADOG to realizacja Kojca, którego konkretnym przypadkiem wykonania jest ów kojec u Kowalskich. Klasa Kojec ALFADOG reprezentuje konkretny typ kojca (produkt rynkowe) na bazie specyfikacji wymagań jaką jest tu klasa Kojec na metamodelu.
Już taki prosty model to nie mało zależności:
Diagram obrazuje związki pomiędzy diagramami i obiektami na nich, można poprzestać na związkach pomiędzy klasami, obiektami itp. Jednak pełny obraz śladowania i kontrola tego śladowania pozwala zapewnić spójność, kompletność i niesprzeczność dowolnie dużego projektu. Czy warto to robić? Ręcznie nie ma sensu z powodu pracochłonności, mając dobre narzędzie CASE nasza godzina pracy nad korektą modeli to ekwiwalent nie raz dziesiątek godzin developera po wykryciu niespójności w tworzonym oprogramowaniu lub wdrażanej zmianie organizacyjnej w firmie. Powyższy diagram to analiza wpływu obiektu Burek na pozostałe elementy projektu. Narzędzie CASE robi to automatycznie w kilka sekund… Aktualizacja całego projektu po zmianie jednego z nich także wykonywana jest automatycznie.
Na zakończenie
Takie analizy i projekty to (u mnie) ok. 70% to projektu programistyczne, pozostałe to analizy dotyczące projektowania reorganizacji, tworzenia wdrażania nowych reguł biznesowych (zarządzania zarządu, tworzenie prawa a kraju). To co tu opisałem, to tak na prawdę szeroko pojęta analiza systemowa. Modelowanie to jedyna możliwość oderwania się od tysięcy detali świata realnego. Bez tego człowiek nie jest w stanie niczego skutecznie analizować czy projektować z uwagi na zbyt duży poziom złożoności. UML (i nie tylko) to narzędzie do tworzenia abstrakcji i metamodeli, bez czego żadna dobra analiza sie obejść nie może.
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.
Tym razem o kilku powszechnie popełnianych błędach w korzystaniu z UML. Chodzi o pojęcia abstrakcji, metamodeli i zależności oraz o związki między elementami na diagramach. Kluczową, moim zdaniem, przyczyną tworzenia „złych” modeli obiektowych jest używanie notacji UML do tworzenia modeli strukturalnych, nie mających z obiektowym paradygmatem nic wspólnego. Druga to niezrozumienie pojęcia paradygmatu obiektowego. Ogromna ilość diagramów wykonanych z użyciem symboli notacji UML, z UML i paradygmatem obiektowym ma niewiele wspólnego.
Najpierw kilka definicji i pojęć.
Paradygmat programowania (ang. programming paradigm) ? wzorzec programowania komputerów przedkładany w danym okresie rozwoju informatyki ponad inne lub ceniony w pewnych okolicznościach lub zastosowaniach. (Źródło: Paradygmat programowania ? Wikipedia, wolna encyklopedia)
No to teraz obiektowy paradygmat:
Programowanie obiektowe (ang. object-oriented programming) ? paradygmat programowania, w którym programy definiuje się za pomocą obiektów ? elementów łączących stan (czyli dane, nazywane najczęściej polami) i zachowanie (czyli procedury, tu: metody). Obiektowy program komputerowy wyrażony jest jako zbiór takich obiektów, komunikujących się pomiędzy sobą w celu wykonywania zadań. Podejście to różni się od tradycyjnego programowania proceduralnego, gdzie dane i procedury nie są ze sobą bezpośrednio związane. (Źródło: Programowanie obiektowe ? Wikipedia, wolna encyklopedia)
albo:
Programowanie obiektowe lub inaczej programowanie zorientowane obiektowo (ang. object-oriented programing, OOP) to paradygmat programowania przy pomocy obiektów posiadających swoje właściwości jak pola (dane, informacje o obiekcie) oraz metody (zachowanie, działania jakie wykonuje obiekt). Programowanie obiektowe polega na definiowaniu obiektów oraz wywoływaniu ich metod, tak aby współdziałały wzajemnie ze sobą. (Źródło: Programowanie obiektowe ? Encyklopedia Zarządzania)
Słownik języka polskiego mówi:
współdziałać 1. ?działać wspólnie z kimś? 2. ?przyczyniać się do czegoś razem z innymi czynnikami? 3. ?o mechanizmach, narządach itp.: funkcjonować w powiązaniu z innymi?
wywołać ? wywoływać 1. ?wołaniem skłonić kogoś do wyjścia skądś? 2. ?przypomnieć sobie lub innym coś? 3. ?spowodować coś lub stać się przyczyną czegoś? 4. ?oznajmić coś publicznie? 5. ?oddziałać na kliszę, błonę lub papier fotograficzny środkami chemicznymi w celu uwidocznienia obrazu utajonego na materiale światłoczułym?
Tak więc stwierdzenie, że „obiekty z sobą współdziałają” oznacza, że „wywołują się” wzajemnie w celu spowodowania czegoś konkretnego. Innymi słowy obiekty tworzące program (system) są od siebie wzajemnie uzależnione. Dlatego podstawowym związkiem w procesie analizy i projektowania zorientowanego obiektowo jest wzajemna „zależność”, nazywana w oryginalnej specyfikacji UML związkiem „usługodawca-usługobiorca”.
Zależności
Związek ten należy utożsamiać z każdą wzajemną zależnością. Z uwagi na to, że mamy wiele typów zależności, wskazujemy konkretny typ z pomocą stereotypu («[nazwa_typu]»).
Najczęściej występujący typ zależności to związek użycia. Oznacza on, że jeden obiekt wywołuje umiejętności (operacje) innego czyli „używa go” do realizacja swojego zadania. Związek taki oznaczany stereotypem «use»:
F używa (jest zależny od) E (co do zasady tu F nie jest samodzielny „w tym co robi”).
Dokumentowanie detali struktury elementów np. repozytorium, wymaga stworzenia kolejnego diagramu: modelu struktury obiektów reprezentujących np. złożoną strukturę obiektu niosącego informacje (np. z formularza).
Korzystamy tu ze związku realizacja i związku kompozycja. Realizacja to związek pomiędzy specyfikacją a jej realizacją (projektem, implementacją, itp.), wskazuje zależność implementacji od jej modelu. C2 jest specyfikacją (opisem, dokumentacją) realizacji D2. Najczęściej związek ten jest stosowany pomiędzy specyfikacją interfejsu a jego implementacją a także generalnie pomiędzy abstrakcją a jej realizacją. Typowym przykładem użycia tego związku jest np. pokazanie na jednym diagramie abstrakcji bytu w repozytorium i realizacji jej struktury:
Na diagramie użyto także związku „całość-część”: linia zakończona wypełnionym rombem na jednym końcu. Romb wskazuje na „całość”: element nadrzędny drzewiastej struktury konstrukcji. Jest to specjalny związek oznaczający trwałe (konstrukcyjne) powiązanie pomiędzy detalami składającymi się na określoną całość. UWAGA! Nie ma on nic wspólnego z pojęciem „relacji” znanym z teorii relacyjnych baz danych!
Biorąc pod uwagę fakt, jakim jest hermetyzacja jako cecha obiektowych konstrukcji, takie „entities” nie współdzielą miedzy sobą ŻADNYCH elementów (danych). Użycie „na dnie” bazy danych, wspólnej dla całej aplikacji, bazy doprowadzonej do tak zwanej znormalizowanej postaci, łamie wszelkie zasady obiektowych konstrukcji: łamie podstawową zasadę jaką jest hermetyzacja implementacji obiektów (zakaz jakiegokolwiek współdzielenia czegokolwiek, nie należy mylić współdzielenia z re-użyciem).
Generalizacja i asocjacja
Oprócz modeli struktur, powstają często modele pojęciowe. Są to odrębne diagramy. Ich celem jest dokumentowanie związków semantycznych i syntaktycznych pomiędzy kluczowymi pojęciami wykorzystywanymi w projekcie. Stanowią one nazwy obiektów i ich typy (atrybuty klas to także obiekty). Wykorzystywane są tu dwa rodzaje związków: generalizacja i asocjacja. Są to związki reprezentujące WYŁĄCZNIE logiczne powiązania pomiędzy pojęciami, nie modelują one struktur a ni implementacji!
Jeżeli jakieś pojęcie ma swoje specjalizowane typy, lub z drugiej strony, grupa pojęć daje się uogólnić innym nadrzędnym pojęciem (generalizowanie), stosujemy związek generalizacji. Związek ten (korzystanie z niego) ma sens tylko gdy liczba typów to co najmniej dwa, co do zasady związek generalizacji służy do grupowania. Jeżeli pomiędzy pojęciami istnieje związek wynikający z dziedziny problemu (np. związek pomiędzy zwierzęciem a karmą dla niego) modelujemy go linią ciągłą łączącą powiązane tak pojęcia. Poniżej graficzny przykład użycia tych związków:
B1 i B2 to konkretne typy pojęcia A (typem jest także pojęcie). Analogicznie B12 i B22 to typy pojęcia A3. Pomiędzy pojęciami A i A3 istnieje związek logiczny (można go nazwać, wpisując te nazwę na linii). Typy mogą mieć więcej niż jeden kontekst dlatego mogą zostać pogrupowane a każda grupa otrzymuje nazwę „nazwa grupy” (oryg. Generalization Sets). Nie ma sensu związek generalizacji pomiędzy tylko jedną parą pojęć, bo oznacza wtedy po prostu tożsamość. Np. pojęcie „województwo” w Polsce ma obecnie szesnaście specjalizacji, mają one swoje nazwy, i to jest jedna grupa typów. Jednak województwa można podzielić także np. ze względu na wielkość na np. trzy grupy: małe województwo, średnie województwo i duże województwo, i to będzie druga i niezależna grupa typów.
Modele…
Wszystkie powyższe przykłady to diagramy klas notacji UML, jednak jak widać każdy ma zupełnie inne przeznaczenie (jest modelem czego innego). Nie omawiałem tu zupełnie diagramów klas modelujących kod programów. Zaznaczę jedynie, że są to kolejne modele dokumentowane z użyciem diagramów klas notacji UML, i omówione powyżej związki dziedziczenia i asocjacje na modelach pojęciowych mają tam zupełnie inne znaczenie.
Modele mogą być różne i dotyczyć różnych rzeczy (patrz Modele.…). Tu chcę zwrócić uwagę na bardzo ważny aspekt: abstrakcyjne i rzeczywiste pojęcia w modelach (na diagramach). Dostrzegam ogromny bałagan nie tylko w dokumentach projektowych ale także i w literaturze, gdzie autorzy pokazują wiele różnych przykładów, które niestety są złe i pozbawione uzasadnienia.
Przede wszystkim modele dzielimy, jak już wspomniałem, na pojęciowe i te modelujące jakąś określoną rzeczywistość. Modele pojęciowe to modele pokazujące pojęcia oraz semantyczne i syntaktyczne związki miedzy nimi. Modele pojęciowe służą do udokumentowania dziedzinowej taksonomii co z jednej strony pozwala utrzymać pełną jednoznaczność dokumentacji a z drugiej, na etapie implementacji, pozwala podejmować decyzje o typach danych. Służą one np. do budowania słowników i etykietowania np. pól formularzy (pole Nazwa województwa, którego zawartość będzie wybierana ze słownika zawierającego szesnaście nazw). Na tych modelach pojawiają się w zasadzie wyłącznie pojęcia stanowiące abstrakcje i typy, nie są to modele żadnego kodu, dziedziny itp. Tu przypomnę, że model dziedziny systemu to model opisujący mechanizm jego (systemu, aplikacji) działania, reprezentowany jest przez literkę M we wzorcu MVC, poważnym błędem jest uznawanie tych modeli za modele danych.
Modele struktury to modele opisujące określone „konstrukcje”, głównie na dwóch poziomach abstrakcji: jako model i jako metamodel. Z reguły, w projektach związanych z oprogramowaniem, ta konstrukcja to właśnie Model Dziedziny czyli mechanizm działania, tak zwana logika biznesowa/dziedzinowa aplikacji.
Podsumowanie
Tak więc nie ma czegoś takiego jak „diagram klas dla projektu”. Mamy dla danego projektu: model pojęciowy, modele logiki systemu, modele struktury obiektów, modele implementacji. To wszystko są diagramy klas ale każdy z nich do model „czegoś innego”. Paradygmat obiektowy jasno mówi: obiekty współpracują, więc standardowym związkiem w modelach logiki działania są związki użycia a nie asocjacje ani związki dziedziczenia czy kompozycji. Diagramy te nie są żadnymi modelami danych między innymi dlatego, że z zasady paradygmat obiektowy ukrywa je (hermetyzacja), „na zewnątrz” dostępne są wyłącznie publiczne operacje obiektów. Utrwalanie obiektów (zapis wartości atrybutów np. w bazie danych) to zadanie do rozwiązania dopiero na etapie implementacji, polegające na zagwarantowaniu „zachowania” stanów obiektów na czas wyłączenia zasilania, by nie „uleciały” z pamięci komputera, który jest środowiskiem wykonania programu. Na etapie analizy obiektowej i modelowania logiki systemu nie modelujemy żadnych danych.
Poniższy przykład, jakich wiele w sieci, jest wzorcowym antyprzykładem.
Pierwsza zła cecha tego diagramu to częsty błąd nazywany popularnie „przeciążaniem obiektów”: tu obiekt Faktura ma operacje „sporządź”. Klasyczny błąd architektoniczny polegający na obciążaniu obiektu cudzą odpowiedzialnością. Jeżeli klasa Faktura reprezentuje np. faktury sprzedaży, to system mający w pamięci kolekcję setek faktur i każda z kodem (ma te operację) służącym do jej sporządzenia byłby masakrą zajętości pamięci. Dodam, że model taki nie ma nic wspólnego z rzeczywistością, bo faktury wystawia „ktoś” a nie „faktura”. Trzecia rzecz: faktura zakupu i faktura sprzedaży to niczym nie różniące się struktury, więc tworzenie takiego rozróżnienia jest pozbawione sensu. To błędy pojęciowe i ten diagram ma masę takich błędów. Druga wada: błędne użycie związku kompozycji: powyższy diagram należałoby interpretować jako strukturę o jednej zwartej konstrukcji, np. takiej jak samochód składający się z setek podzespołów ale stanowiący jednak jedną całość. Brak modelu pojęciowego i słownika powoduje wiele niejednoznaczności. Np. związek pomiędzy Klientem a reklamacją wskazuje, że Reklamacje są integralną częścią Klienta (tak jak koła i silnik są integralną częścią samochodu) co nawet w świetle potocznego rozumienia tych słów kłóci się ze zdrowym rozsądkiem.
Użycie związków pojęciowych (asocjacja) jest zupełnie niezrozumiałe w tym przypadku. Nazwa asocjacji „zawiera” nie ma kierunku a więc nie wiadomo co jest zawarte w czym. Związki zależności także są niejasne: jak interpretować np. zapis mówiący, ze obiekty klasy użytkownicy zależą od obiektów klasy Raporty? Jeżeli autor miał na myśli „użytkownik używa raportów” to popłynął w sferę „mowy potocznej”, to chyba najczęściej spotykany błąd polegający na tym, że autor diagramu nadal pisze specyfikację prozą, ale z użyciem symboli (tu UML) zamiast słów.
Mogę się jedynie domyślać, że autor diagramu „miał w głowie” model relacyjny związków encji i użył ikon z notacji UML w całkowicie innych znaczeniach niż ta notacja definiuje. Takie diagramy nie powinny powstawać, są one niestety dowodem na to, że programiści mówiący „te dokumenty z UML nic nie wyjaśniają i są nieprecyzyjne, i tak musimy sami powtórzyć te analizę” mają rację. Są także dowodem, że są to jednak projekty strukturalne a nie obiektowe, a użycie notacji UML polegało na skorzystaniu z zestawu ikon tak się to robi tworząc niesformalizowane schematy blokowe z użyciem np. programów do tworzenia prezentacji takich jak PowerPoint. Zapewne poza autorem tego diagram, nikt nie ma pojęcia o co w nim chodzi.… Jeżeli autor miał na celu udokumentowanie „modelu danych” to powinien użyć notacji ERD. A tak to mamy schemat blokowy, w którym ktoś użył UML jako biblioteki symboli wprowadzając czytelnika w błąd.
Niestety „sprawne” korzystanie z takich specyfikacji wymaga umiejętności czytania modeli pojęciowych (diagramów klas UML) opisujacych syntaktykę (syntax) jak wyżej (ich tworzenie też do łatwych nie należy…). Przytaczam to jako źródło tego o czym tu pisałem.
W UML „wszystko jest klasą”, związki między elementami diagramów także. Zostało to pokazane w specyfikacji UML v.2.5.:
W UML 2.5 praktycznie znika w końcu dziedziczenie i agregacja. Uff… poniżej podsumowanie na jednym diagramie.
Dodatek [2022 – 07-22]
…chciałbym zapytać o dziedziczenie w UML. Brałem ostatnio udział w kilku rozmowach o pracę. Moi rozmówcy często utrzymują, że w UML jest to dziedziczenie. Mało tego, wykorzystują to dziedziczenie na diagramach klas, w czymś co nazywają modelem dziedziny (oczywiście bez operacji klas). Zajrzałem do specyfikacji UML i jestem trochę zdezorientowany, ponieważ pojęcie dziedziczenie dość często występuje w tej dokumentacji, choćby w tym fragmencie.
W jakim znaczeniu jest tu użyte pojęcie dziedziczenia? Czy jest gdzieś w specyfikacji wprost informacja o usunięciu dziedziczenia z UMLa?
Porównując ze specyfikacją 2.4. nie ma, pojęcie dziedziczenia nadal jest obecne w językach programowania, a w specyfikacji 2.5.xx słowo „inheritance” pojawia sie tylko 4 razy, i dotyczy wyłącznie komentarzy związanych z uogólnieniami.
Cytowany związek Generalizacji jest związkiem pojęciowym a nie strukturalnym czegoś istniejącego (struktura modelowanego systemu). Formalnie w UML mamy związek Generalizacji, i jest to związek pojęciowy, ale nie ma w UML rozdziału „Dziedziczenie”. Inherit w j. angielskim to także „przejęcie cech po czymś” czyli związek generalizowania i specjalizowania. Generalziacja, jako związek ogólny-szczególny, pokazuje że szczególny przypadek, pojęcie i jego definicja, ma wszystkie cechy przypadku ogólniejszego, więc pies jako szczególny typ ssaka ma wszystkie cechy ssaka (chodzi o definicje tego czym jest ssak). Czyli: 1. ssak: kręgowiec, którego młode karmią się mlekiem matki, 2. pies: <ssak> który szczeka, więc:
pies: <kręgowiec, którego młode karmią się mlekiem matki>, który szczeka,
czyli pies (a konkretnie definicja psa) „dziedziczy” po ssaku (definicji ssaka) jego określone cechy, czyli oznacza to, że są one (cechy ssaka) np. dla psa i kota wspólne, a nie że, kot czy pies coś „dziedziczy” po ssaku :).
Dlatego w UML teraz jest napisane, że mamy generalizację jako związek między klasami, ale nigdzie nie ma związku „dziedziczenia” między klasami.
Tekst rozdz. 9.2.3.2. tłumaczymy tak, ze generalizacja oznacza, że generalizowana definicja (cechy czyli atrybuty i zachowania) są wspólne (dziedziczą) dla specjalizowanych elementów. W modelu pojęciowym (namespace) tak to działa. I teraz: model struktury czegokolwiek istniejącego nie ma abstrakcji (a generalizowane pojęcia to abstrakcje, pojęcie ssak to pojęcie abstrakcyjne). Opisując więc traktor jako pojazd czy dokumenty w księgowości jako dokuenty, nie ma nad nimi „uogólnień”, po których dziedziczą (sa to jednak pojęcia słownikowe). Po trawie nie biegają „ssaki” tylko psy, koty, lwy…
Znakomita większość znanych mi ludzi w IT nie odróżnia modelu pojęciowego od modelu struktury systemu, który zbudowany jest (każdy) z realnych elementów. W miejsce „starego” dziedziczenia w UML wprowadzono pojęcia: szablon (template) oraz rola (realnym czymś w samochodzie jest „silnik”, pojęcie „napęd” to nazwa funkcji/roli określonego komponentu, ale nie piszemy: „<silnik> dziedziczy po <napędzie>” tylko „<silnik> pełni rolę <napędu>” tak samo jak nie powiemy „<pies> dziedziczy po <zwierzę domowe>” tylko „<pies> pełni rolę <zwierzęcia domowego>”.
Języki programowania pozwalają na tak zwane re-użycie kodu, czyli wyciąganie pewnych wspólnych cech ponad konkretne komponenty/klasy (abstrakcja) po to by tylko raz pisać kod komponentów mających wspólne cechy. Jednak projektując „model dziedziny” nie ma w niej abstrakcji, mając model dziedziny (mechanizm działania aplikacji) zamieniamy generalizacje i „dziedziczenia” pojęciowe na atrybuty i typy realnych rzeczy, tak to opisano książce o modelowaniu systemów już w 2007 roku:
Oczywiście programista może używać gdzie chce dziedziczenia (ma taką możliwość w każdym obiektowym języku programowania) ale to jedna z najgorszych praktyk, bo łamiących kluczową zasadę jaką jest hermetyzacja komponentów („zakaz” współdzielenia czegokolwiek). To dlatego od wielu lat OOP (Object-oriented Programming, języki i programowanie obiektowe) i OOAD (Object-oriented Analysis and Design) to odrębne „dziedziny”.
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.
Dzisiaj będzie bardzo krótki wpis, którym niemalże w całości będzie cytat z artykułu pewnego programisty. Każdy analityk i projektant powinien przeczytać cały artykuł (nie jest długi) i koniecznie komentarze pod nim. Jeden komentarz zacytuje bo jest znamienny, choćby dlatego, że moje doświadczenia są dokładnie takie same:
Co Ty człowieku, życia nie znasz? Przecież w realu jakbyś poszedł do takiego i podzielił się takimi uwagami to foch na pare tygodni co najmniej gwarantowany. Kiedyś miałem podobną sytuację (a raczej serię sytuacji, ale dotyczących rzeczy o mniejszej skali) to efekt był taki, że wolałem zmienić robotę 😉
A teraz zapraszam do lektury tekstu, który napisał nie analityk a programista (a kim jest to polecam jego CV na stronie):
Jak to z każdym językiem bywa, niekiedy jesteśmy w stanie wydobyć bardzo wiele nawet bez zbytniego wgłębiania się w szczegóły, po prostu wiemy, że niektóre rzeczy są ważniejsze niż inne. Tak jak w zdaniach, których spójnikiem jest ?ale?. Każdy wie, że wszystko to, co przed owym ?ale? się znajduje jest niewarte słuchania 😛 I właśnie kilka takich przypadków chciałbym dzisiaj opisać. Sytuacji, w których rozumienie całego kontekstu jest zbędne, wystarczy szybki rzut okiem na diagram, aby wiedzieć co jest najważniejsze.
W omawianych przeze mnie przypadkach chodzi o szybkie wyłapanie błędów projektowych, bez konieczności zagłębiania się w logikę, która kryje się za diagramami. (Programistyka: Diagram prawdę Ci powie)
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.
Strona używa plików cookie, aby zapewnić Ci wygodę przeglądania poprzez zapamiętywanie Twoich preferencji i powtarzających się wizyt. Klikając "Akceptuj wszystko", wyrażasz zgodę na użycie WSZYSTKICH plików cookie. Jednakże, możesz odwiedzić "Ustawienia plików cookie", aby zapewnić kontrolowaną zgodę.
Ta strona korzysta z plików cookie, aby poprawić wygodę podczas podczas przeglądania witryny. Pliko cookie, które są sklasyfikowane jako niezbędne, są przechowywane w przeglądarce, ponieważ są niezbędne do działania podstawowych funkcji witryny. Używamy również plików cookie stron trzecich, które pomagają nam analizować i zrozumieć, w jaki sposób korzystasz z tej witryny. Te pliki cookie będą przechowywane w przeglądarce tylko za Twoją zgodą. Możesz również zrezygnować z tych plików cookie. Ale rezygnacja z niektórych z tych plików cookie może mieć wpływ na wygodę przeglądania.
Niezbędne pliki cookie są absolutnie niezbędne do prawidłowego funkcjonowania witryny. Ta kategoria obejmuje tylko pliki cookie, które zapewniają podstawowe funkcje i zabezpieczenia strony. Te pliki cookie nie przechowują żadnych danych osobowych.
Wszelkie pliki cookie, które mogą nie być szczególnie potrzebne do działania witryny i są wykorzystywane w szczególności do gromadzenia danych osobowych użytkowników za pośrednictwem analiz, reklam i innych treści osadzonych, są określane jako niepotrzebne pliki cookie. Wymagane jest uzyskanie zgody użytkownika przed uruchomieniem tych plików cookie w witrynie.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Cookie
Duration
Description
__atuvc
1 year 1 month
AddThis sets this cookie to ensure that the updated count is seen when one shares a page and returns to it, before the share count cache is updated.
__atuvs
30 minutes
AddThis sets this cookie to ensure that the updated count is seen when one shares a page and returns to it, before the share count cache is updated.
bcookie
2 years
LinkedIn sets this cookie from LinkedIn share buttons and ad tags to recognize browser ID.
bscookie
2 years
LinkedIn sets this cookie to store performed actions on the website.
language
session
This cookie is used to store the language preference of the user.
lidc
1 day
LinkedIn sets the lidc cookie to facilitate data center selection.
na_id
1 year 24 days
The na_id is set by AddThis to enable sharing of links on social media platforms like Facebook and Twitter.
ouid
1 year 24 days
Associated with the AddThis widget, this cookie helps users to share content across various networking and sharing forums.
vc
1 year 24 days
The vc cookie is set by addthis.com on sites that allow sharing on social media.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Cookie
Duration
Description
at-rand
never
AddThis sets this cookie to track page visits, sources of traffic and share counts.
browser_id
5 years
This cookie is used for identifying the visitor browser on re-visit to the website.
CONSENT
2 years
YouTube sets this cookie via embedded youtube-videos and registers anonymous statistical data.
uid
1 year 24 days
This is a Google UserID cookie that tracks users across various website segments.
uvc
1 year 1 month
Set by addthis.com to determine the usage of addthis.com service.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Cookie
Duration
Description
di2
1 year 24 days
AddThis sets this cookie on sites that allow sharing on social media. It is used to track user behaviour anonymously, to create usage trends that will improve relevance to their services and advertising.
loc
1 year 1 month
AddThis sets this geolocation cookie to help understand the location of users who share the information.
um
1 year 24 days
Set by AddThis for registering the user's sharing of content through social media.
VISITOR_INFO1_LIVE
5 months 27 days
A cookie set by YouTube to measure bandwidth that determines whether the user gets the new or old player interface.
YSC
session
YSC cookie is set by Youtube and is used to track the views of embedded videos on Youtube pages.
yt-remote-connected-devices
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt-remote-device-id
never
YouTube sets this cookie to store the video preferences of the user using embedded YouTube video.
yt.innertube::nextId
never
This cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.
yt.innertube::requests
never
This cookie, set by YouTube, registers a unique ID to store data on what videos from YouTube the user has seen.