Swego czasu pod artykułem Business Model vs. System Model, wywiązała się dyskusja, po tym jak napisałem, że oprogramowanie reprezentuje narzędzie pracy, więc projekt tego oprogramowania raczej powinien zawierać pojęcie (klasę) Karteka Pracowników a nie Pracownicy. Jeden z czytelników napisał wtedy (dociekliwym polecam w tym momencie cała tę dyskusje pod artykułem):
… byt Pracownik jak najbardziej ma sens. Przecież tu jest zdefiniowane jego zachowanie (część jedynie z real world, ale jednak). Pracownik.pijeKaweRano().. przeciez nie KartotekaPracownika.pijeKaweRano() (Business Model vs. System Model).
Gdzie problem?
Regularnie na szkoleniach i w projektach miewam dyskusje inicjowane pytaniem: Dlaczego nie podoba się Panu klasa Pracownik? No właśnie: Dlaczego nie podoba mi się klasa Pracownik?
Najpierw kluczowy dla każdego projektu diagram przypadków użycia czyli wymagania i kontekst projektu:
Jest to hipotetyczny diagram opisujący prosty program do sprzedaży. Tu pierwsza uwaga, zanim coś nazwiemy 'system’ należy pamiętać, że
System (stgr. ??????? systema ? rzecz złożona) ? obiekt fizyczny lub abstrakcyjny, w którym można wyodrębnić zespół lub zespoły elementów wzajemnie powiązanych w układy, realizujących jako całość funkcję nadrzędną lub zbiór takich funkcji (funkcjonalność). (System ? Wikipedia, wolna encyklopedia).
Systemem więc może być oprogramowanie i wtedy mamy tu System wspomagający sprzedaż towarów. Ale pracownicy firmy współdziałają z tym oprogramowaniem, (korzystają z niego), więc oni wraz z oprogramowaniem, jako cała firma (organizacja) także są systemem. Zgodnie z ogólna teorią systemów „system to system systemów”, z perspektywy badanego Systemu mamy jeszcze podsystem (system składowy) i supersystem (system nadrzędny). Jeżeli więc nazywamy nasze oprogramowanie System to znaczy, że firma wraz z jej pracownikami i wyposażeniem to Supersystem, a ewentualne komponenty Systemu wspomagającego sprzedaż towarów to podsystemy. Innymi słowy mamy tu dwa systemy: jeden obwiedziony linia przerywaną czyli ludzie używający oprogramowania do pełnienia swoich obowiązków, drugi będący projektowanym oprogramowaniem.
Pierwsza uwaga: bardzo często obserwuję, że już na etapie analizy zapomina się, że analizowana organizacja to ów Supersystem, do którego należy stosować takie same zasady jak do Systemu. To znaczy, że chcąc opracować wymagania na System należy przeanalizować Supersystem. Powodem wielu porażek wdrożeń jest zignorowanie tego faktu, rzucamy się na wdrożenie np. Systemu ERP nie mając pojęcia o jego „roli” w Supersystemie (naszej organizacji), który tym wdrożeniem można nawet zniszczyć. Z moich obserwacji wynika, że jest to jedna z kluczowych przyczyn porażek wielu wdrożeń Systemów CRM, które na ich – tych CRM’ów – nieszczęście często dotyczą całej organizacji.
I teraz wyjaśnienie: Supersystem (zaznaczony jako Współdziałanie) ma Magazyniera i Sprzedawcę wiec System ich już nie ma (oni są Aktorami na zewnątrz). Magazynier (pamiętamy, że nie wolno w jednym systemie – przestrzeni nazw – używać twego samego pojęcia w więcej niż jednym znaczeniu) to „osoba przyjmująca i wydająca towary z magazynu” więc to słowo już zarezerwowaliśmy w projekcie, nie należy go więc używać powtórnie w innym znaczeniu. Tak więc nasz Supersystem to nasi pracownicy używający do pracy Systemu wspomagającego sprzedaż towarów.
Pora na model dziedziny systemu. Tu delikatnie przypomnę, wcześniejszy artykuł: Czym jest a czym nie jest tak zwany model dziedziny systemu. Jeżeli ktoś go nie czytał to to jest właściwy moment. Drugi scenariusz to przeczytanie go po tym, wtedy zapewne tezy tam prezentowane będą oczywiste.
Model dziedziny naszego Sytemu (to jakaś wstępna, zapewne wymagająca jeszcze pracy wersja ale chodzi o zasady :)):
Przypominam, że powyższe to model dziedziny systemu czyli nie model pojęciowy i na pewno nie model danych. Jest to diagram klas (zastosowałem ikony wzorca BCE) opisujący współpracę obiektów, bo zgodnie z definicją obiektowego paradygmatu:
Program obiektowy należy postrzegać jako kolekcję współdziałających obiektów, w przeciwieństwie do konwencjonalnego modelu programowania, gdzie program to lista poleceń (zadań, podprogramów) [przyp. mój] operujących na określonym zestawie danych (baza danych). (Czym jest a czym nie jest tak zwany model dziedziny systemu).
Klasy nie mają więc na tym etapie analizy i projektowania atrybutów, bo do analizy i zrozumienia problemu są zupełnie zbędne. Mają zaś operacje, bo te są niezbędne dla zrozumienia problemu i opracowania jego modelu.
No więc dlaczego nie podoba mi się klasa Pracownik? Bo pracownik to Aktor Systemu, a System ten przechowuje wybrane dane o tym pracowniku. Są to dane potrzebne np. do identyfikowania osób wystawiających dokumenty z Systemu, a do tego potrzebne są jedynie Karty Pracowników a nie Pracownicy. System (oprogramowanie) zastąpił papierowe Kartoteki Magazynowe dlatego są one teraz w Systemie, ale towary są w nadal magazynie (a nie w Systemie), system „ma w środku” Kartę Towaru (zastąpiła papierową) zawierającą opis towaru i jego ilość w magazynie. Kartoteka Magazynowa to pudło zawierające Karty Towarów. Faktura VAT to obiekt w systemie, można ją wydrukować lub wysłać jej egzemplarz w postaci elektronicznej kontrahentowi.
Co uzyskujemy dzięki temu:
- Nie ma problemu z tym co oznacza w dokumentacji projektu np. słowo Pracownik (wiadomo, że to aktor a nie klasa dziedzinowa).
- System ten jest tym czym jest, czyli narzędziem pracy człowieka a nie np. człowiekiem.
- Model dziedziny, z niewielka pomocą, jest zrozumiały dla biznesu (tu ewentualna ewolucja modelu do wzorców DDD).
- Model ten nadaje się do bezpośredniej implementacji (no prawie ;))
Kilka słów komentarza do praktyk i użytych wzorców. Cały problem został rozłożony na trzy analityczne składniki: obiekty graniczne (Boundary, klasy z pozioma literką T) odpowiedzialne za to jak System świadczy usługi swoim aktorom (Aktor to Użytkownik Systemu). Obiekty posiadające wiedzę o wybranych aspektach działania Systemu i świadczące wewnątrz systemu takie usługi, np. o tym jak utworzyć Fakturę czy Kartotekę (strzałka zawinięta w kształt koła). Obiekty reprezentujące unikalne, zapamiętywane „istnienia” takie jak faktury, kartoteki itp. (Entity, klasy w postaci koła z poziomą linią u dołu).
Pytanie – czy faktycznie każdy pracownik jest Aktorem?
A kto tu mówi, że każdy :), wskazałem dwóch. Po drugie jednak patrząc na Organizacje jak na system, to to że jakiś pracownik nie jest aktorem nie znaczy, że nie jest „współdziałającym” elementem systemu i należy go w analizie zignorować. Pani na recepcji nie jest aktorem systemu FK, ale odbiera faktury od listonosza i przynosi, w kategorii całej firmy ma wpływ na to jak długo potrwa proces biznesowy od doręczenia faktury do jej zapłacenia. Problem wielu projektów to przedwczesne określenie zakresu projektu na bazie „hipotezy”, np. wydaje nam się, ze chcemy CRM. I cała analiza ogranicza się np. do działu handlowego. Całość strasznie kuleje bo odkrywane są jakieś potrzebne dane z innych działów, albo okazuje się, że np. faktury wystawiane są jednak w dziale księgowości a potrzebne są w CRM. Dlatego znacznie lepsza jest kolejność: określenie celu biznesowego, analiza (na określonym poziomie szczegółowości) działania całej organizacji, określenie zakresu projektu na bazie pozyskanej wiedzy i celu biznesowego, analiza wymagań i projektowanie oprogramowania. Większość firm startuje od ostatniego punktu… A zdarzało mi się, że projekt o początkowej nazwie CRM skończył się jako projekt Elektroniczny obieg dokumentów.
Pytam, bo tekst na to wskazuje:
„No więc dlaczego nie podoba mi się klasa Pracownik? Bo pracownik to Aktor Systemu, a System ten przechowuje wybrane dane o tym pracowniku.”
ORAZ:
„Nie ma problemu z tym co oznacza w dokumentacji projektu np. słowo Pracownik (wiadomo, że to aktor a nie klasa dziedzinowa).”
Jeżeli są pracownicy, którzy nie są aktorami (pani na recepcji), to powyższe argumenty przeciwko klasie Pracownik nie są przekonujące.
Czym się różni pracownik – użytkownik systemu od pracownika – nieużytkownika? Wyłącznie uprawnieniami, które z dnia na dzień mogą być nadane lub odebrane. Nie uzależniałabym więc struktury modelu od tak eterycznego parametru. Pierwsze skojarzenie z nazwą „Pracownik”: osoba zatrudniona w danym przedsiębiorstwie – czyli definicja SZERSZA, niż Aktor systemu. W klasie Pracownik mogą się więc znaleźć informacje takie jak: Imię, Nazwisko, Zatrudniony_od, Rola itp. atrybuty pracownika.
„Czym się różni pracownik ? użytkownik systemu od pracownika ? nieużytkownika?” – Niczym, jeden z nich jest Aktorem systemu, obaj są elementami „systemu” jaki jest cała organiaacja z jej zasobami (pracownik i oprogramowanie to zasoby firmy). problem w tym, że Pracownik to żywy człowiek, jeżeli System (nasze oprogramowanie) przechowuje jakieś dane o pracownikach (HR o wszystkich), to są to ich dane a nie oni.
Tu nie chodzi o to, czy Pracownik jest czy nie jest Aktorem systemu ale o to, że pojęcie Pracownik zostało zarezerwowane dla pracowników w rozumieniu ludzi. będących „poza oprogramowaniem”. Mówiąc (pisząc) Pracownik Kowalski mam na myśli osobę. Jeżeli klasa nazywa się także Pracownika to po pierwsze to słowo ma teraz dwa znaczenia: klasa oraz osoba mimo tego, ze nie to tożsame byty. Po drugie oprogramowanie „ma w sobie” dane opis tego pracownika a nie jego samego…
„Pierwsze skojarzenie z nazwą ?Pracownik?: osoba zatrudniona w danym przedsiębiorstwie ? czyli definicja SZERSZA, niż Aktor systemu.” – Aktor (użytkownik oprogramowania) to podzbiór zbioru Pracownik, wszystko jest w porządku. Jednak Pracownik owszem ma imię i nazwisko, to jego cechy. Oprogramowanie zawiera elektroniczną kartotekę pracownika, w której zapisano jego imię i nazwisko, a to nie to samo. Jest ogromna różnica pomiędzy mną a moją kartoteką w Urzędzie Skarbowym.
Innymi słowy, w metodach strukturalnych można pewnie obronić tezę, że encja reprezentująca dane o pracowniku (dane pracownika) może się nazywać Pracownik. W metodach obiektowych jednak już raczej nie, gdyż program to narzędzie pracy człowieka (tegoż pracownika), wewnętrzna, obiektowa, struktura oprogramowania to nadal zasoby reprezentowane przez obiekty (implementacje dziedziny). Jeżeli więc papierową kartotekę pracownika zastępujemy elektroniczną, to nadal jest to Kartoteka Pracownika a nie Pracownik 😉
Z punktu widzenia aplikacji Magazynier czy Księgowa to jakiś szczególny rodzaj obiektu Uzytkownika. Nie jest to struktura danych tylko obiekt właśnie, który oprócz konkretnych danych zawiera również metody. Kartoteka pracownika miałby sens jeśli rozpatujemy to w kategoriach modelu (struktury danych), a nie pełnoprawnego obiektu.
Semantycznie, co do zasady, punktem widzenia aplikacji jest jej aktor, to zresztą kluczowy punku wyjścia: model przypadków użycia pokazuje system postrzegany przez Aktora bo dla niego on powstaje. Dla każdego użytkownika oprogramowania np. ERP czyli jego Aktora, Magazynier to zawsze będzie kolega z Magazynu a nie obiekt w Systemie (no może poza przypadkiem pisania gry komputerowej symulującej magazyn :)). Podejście uznające nazywanie klasy i obiekty jak ludzi budzi ogromne nieporozumienia a nie wnosi żadnej nowej wartości do projektu: Magazynier dla użytkownika to kolega z pracy dla programisty klasa i tu kończy się komunikacja w projekcie pomiędzy biznesem a developerem – standardowy problem w projektach tego typu.
W metodach obiektowych nie istnieje pojęcie „struktury danych”, a KartotekaPracownika to obiekt odpowiadzialny za przechowywanie wiedzy o pracowniku i ma operacje np. PodajDanePracowmnika, CzyPracownikMadziśDzieńWolny.
Aktor powinien być odwzorowany w systemie jako obiekt. System musi potrafić rozpoznać aktora. Aktora w systemie coś musi reprezentować po prostu. Nikt nie chce traktować człowieka (użytkownika) jako obiektu. Nie uzyjemy KartorekaMagazyniera.wyloguj() tylko Magazynier.wyloguj().
Czemu pojęcie struktury danych nie istnieje? To nieporozumienie, że wszystko powinno być obiektem. Przykładowo Adres jest strukturą danych (a nie obiektem). Zawiera publiczne właściwości i zero logiki biznesowej. Obiekty natomiast ukrywają swoją implementację udostępniając wyłącznie niezbędne metody.
„Aktor powinien być odwzorowany w systemie jako obiekt.” Skąd ta teza? Ochrona rozpoznaje mnie w biurze bo ma mojego klona w szufladzie czy tylko pewne dane identyfikacyjne i status? A może po prostu użyjemy ListaZalogowanych.Wyloguj(identyfikator_zalogowanego_uzytkownika)?
Adres jest (może być, lepiej gdy jest) obiektem, ma atrybuty: ulica, posesja, lokal, miasto, kod, ma operacje walidujące poprawność adresu i jest to wzorzec ValueObject: obiekt pozbawiony tożsamości reprezentujący pewien złożony typ informacji mający swoja wewnętrzną logikę (np. posesja musi wystąpić ale lokal już nie musi, miasto bez kodu nie ma sensu, jest możliwość sprawdzenia poprawności pary miasto kod itp.)
W OOAP wszystko jest obiektem, ale czasami można obiekt obciążyć odpowiedzialnością za zarządzanie np. całą tablica danych czy plikiem na dysku…
Nie chodzi o odwzorowanie Magazyniera (jako osoby) w systemie. Chodzi o obiekt, który go tam reprezentuje. Z punktu widzenia aplikacji chcemy mieć dostep do zalogowanego użytkownika. Magazynier (jako fasada) może mieć metody typu pobierzPrzypisaneMagazyny() co odróżnia go od innych typów użytkowników.
Co do adresu to jego walidacją powinien zajmować się zewnętrzny obiekt. Różne kraje różnie walidują adres. W Irlandi nie ma kodów pocztowych (chyba) przykładowo. Adres ma tylko zapewnić spójność. Literalnie sturkura jest obiektem oczywiście, chodzi mi o idee. Obiekt nie pozwala na dostep do swoich właściwości i jest hermetyczny, sturktura danych przeciwnie.
Nie wszystko jest obiektem. Nie chce kopiować Internetu bo ten problem został poruszony już w wielu miejscach.
Moim „przesłaniem” jest teza, że dobrze jest traktować cały projekt jako przestrzeń nazw, wtedy słowo Magazynier może mieć tylko jedno znaczenie: albo osoba albo klasa… i o to tu głównie chodzi, ja także nie chce tu brnąc w pomysły na implementacje.
Zawsze miałem problem czy modelować: Pracownik, Pracownicy czy też KartotekaPracowników.
Te wyjaśnienie ma dla mnie sens. Dzięki.
Gwoli wyjaśnienia, nie neguję tego co Pan sugeruje. Po prostu nie do końca umiem sobie tę wizję wyobrazić. Przedstawiam więc swój punkt widzenia na sytuację. Dziękuję za rzeczowe odpowiedzi.