Systemy zarządzania przepływem dokumentów (docflow) lub pracy (workflow), wzorce projektowe i … problem. Uwaga! Jeżeli nie jesteś analitykiem ani projektantem systemów, zalecam skok na koniec tekstu do punktu Na zakończenie biznesowo.
Tym razem chcę zwrócić uwagę na pewien problem ze stosowaniem wzorca projektowego State Machine Pattern. Wzorzec ten moim zdaniem stanowi pułapkę dla niedoświadczonych projektantów i programistów. Otóż wzorzec ten jest dość powszechnie stosowany do implementacji usługi zarządzania przepływem dokumentów. Ale po kolei.
State machine pattern
Wzorzec ten jest dobrze opisany w literaturze więc tu tylko kluczowe informacje. Uproszczony model wzorca:

Kontekst to obiekt statusowy (charakteryzujący się pewną stanowością). Jego częścią jest zestaw (kompozycja z obiektami Status) stanów jakie może on przyjmować (KonkretneStany). Logikę zmian tych statusów umieszcza się w obiekcie Kontekst (operacja ustaw konkretny status jako aktualny), spotykaną metodą implementacji jest umieszczanie operacji reagujących na konkretne zdarzenia w obiektach stanowych. Ten drugi wariant jest w moich oczach troszkę nadużyciem: wiedza o statusach jest wnoszona do statusów, obiekt macierzysty nie panuje nad nimi, a statusy to jednak cecha (własność) obiektu Kontekst i to on „wiek jaki i dlaczego status chce przyjąć”.
Kiedy stosować
Model ten więc bazuje na założeniu, że wiedza o statusie (kiedy jaki przyjąć) tkwi w obiekcie statusowym (przyjmującym te stany). Przykładem może być np. woda i jej stany skupienia, które są cechą fizyczną wody – są więc związane z wodą. Woda może przyjąć stan skupienia stały (lód), ciekły lub gazowy (para wodna). Aktualny stan skupienia zależy wyłącznie od temperatury i ciśnienia. Żaden inny czynnik nie jest w stanie zmienić stanu kupienia wody (np. na polecenie człowieka
). Przykładów takich można przytoczyć wiele.
Problem zaczyna się gdy obiekt ma statusy zależne od pewnej logiki zewnętrznej, jakiś inny obiekt ma wiedzę o tym jaki status zostanie ustawiony. Ciekawym przykładem jest np. nasze mieszkanie (konkretnie zamek w drzwiach) i my. Status Zamknięte i Otwarte nie jest cechą ani zamka, ani drzwi ani nawet mieszkania tylko jest to efekt naszej woli (mieszkańca). To my decydujemy o tym czy mieszkanie jest zamknięte czy otwarte i czy być może ma inny jeszcze status (nie znany producentowi drzwi!). W efekcie logika zmiany statusu jest poza drzwiami (mieszkaniem), które dany stan przyjmują. Mieszkaniec w dowolnym momencie może ustawić swoje mieszkanie w stan nie planowany wcześniej, więc implementacja powyższego wzorca napotka na poważny problem: jak ustawić status nieznany w momencie projektowania? Przykład? W hotelach: posprzątać, nie przeszkadzać itp… Tu można zaryzykować znaną z góry listą takich znaków ale nasze drzwi w domu? Bierzemy tak zwaną żółta karteczkę i naklejamy na drzwi z zewnątrz: jestem zajęty albo co nam tam do głowy przyjdzie (domownik u sąsiada). Implementacja stanów „na żywca” staje się poważnym ograniczeniem bo wzorzec w tej postaci wymaga wiedzy o wszystkich stanach już w momencie tworzenia systemu.
Klasycznym jednak przykładem tego problemu są
Systemy obiegu dokumentów
Dokument (obiekt) biznesowy może przyjmować stany w zasadzie nieprzewidywalne na etapie analizy. Stany te mogą być (i nie raz są!) skutkiem wprowadzania lub zmian reguł biznesowych a nie cech dokumentu. Tak więc znane na początku wdrożenia statusy faktury: przyjęta, zaksięgowana, zapłacona. Mogą się zmienić po wprowadzeniu np. wewnętrznego zarządzenia o treści: dokumenty rodzące koszty przekraczające 10 tys. złotych muszą być dodatkowo zatwierdzane przed Zarząd. Jaki mamy efekt? Wiele dokumentów, nie tylko faktury ale i umowy czy reklamacje nagle muszą obsłużyć nowy status: do zatwierdzenia przez Zarząd. Mamy tu lawinową modyfikację systemu. Zmiana zasad wymaga ingerencji we wszystkie obiekty stanowe mogące „podpaść” pod nową regułę. Pytanie drugie: jak je wszystkie szybko i jednoznacznie zidentyfikować w systemie?
Już czujemy? Kto ma system obiegu dokumentów wymagający ingerencji dostawcy przy każdej zmianie zasad albo dowiaduje się, że „tego niestety nie można zrobić”?
Problem maszyny stanowej: obciążenie dokumentu odpowiedzialnością za jego status, jest w takich przypadkach złamaniem zasady właściwego przydziału odpowiedzialności w projektowaniu obiektowym. Tak więc w takich przypadkach należy zrezygnować z wzorca State machine.
Pewnym rozwiązaniem w obszarze procesów biznesowych i zarządzania przepływem pracy jest
Metamodel procesu WfMC
Workflow Management Coalition to organizacja standaryzująca (więcej w odnośniku). Proponuje ona taki oto metamodel (tu diagram nieco uproszczony):

(źr. WfMC: http://www.wfmc.org/standards/docs/TC-1011_term_glossary_v3.pdf)
Nasz obiekt statusowy, np. dokument, to DanePowiązane. Jednak statusy ustawia mu nie „on sam sobie” a Aktywność na bazie „wiedzy” zapisanej w obiekcie WarunekPrzekształcenia (WywołanaAplikacja to przypadek, gdy status uruchamia jakieś przetwarzanie Danych, tu nie będzie to omawiane, przydaje się np. przy projektach SOA). Aktualny status DanychPowiązanych to ich atrybut. Jak go ustawić? Poleceniem „ustaw status na …” gdzie parametrem jest „kod statusu” (lub obiekt go reprezentujący, o czym za moment). Mógł by ktoś zarzucić mi upublicznienie dostępu do atrybutów (jest zasada by tego nie robić) ale to właśnie jeden z tych przypadków gdy atrybut obiektu nie jest jego własnością. Po drugie nie upubliczniam dostępu do atrybutu. Zarządza nim operacja obiektu „ustaw status na…” i nie jest to niebezpieczne get/set. Tu nie udostępniam atrybutu a ujawniam jego istnienie a to nie to samo. Po drugie kontroluję błędy właśnie dedykowaną operacją, która może kontrolować poprawność wykonania (np. sprawdzając czy przekazywany parametr jest dopuszczalny). Kompletny opis (przepis) takiej logiki to Proces a odpowiedzialność za Aktywności ma Rola czyli jakiś aktor systemu.
Ta propozycja jest zgodna z „zadami sztuki OOAD” a rozbierając ją na czynniki pierwsze także z DDD. Zwróćmy uwagę, że model, w którym Aktywność ustawia status Danych jest zgodny z tym, że wiedzę o statusach ma Aktywność i ma swobodę ich ustawiania. Po drugie taki projekt ma w jednym tylko miejscu zgromadzona wiedzę o regułach i dopuszczanych statusach. W takiej sytuacji nawet jeżeli pojawi się nowy, nie znany nam wcześniej obiekt biznesowy, możemy go łatwo stworzyć bez potrzeby wbudowywania mu z góry jego statusów. Zmiany zestawu możliwych statusów (nowe zarządzenie) dokumentów nie wymagają przeróbek całego zestawu zaimplementowanych obiektów biznesowych. Takie podejście daje także możliwość pracy ad-hoc (ustawienie statusu dokumentu lub sprawy „z palca”).
O DDD. Status dokumentu (dokument to Encja w DDD) nie musi mieć tożsamości więc może być implementowany jako VO (Value Object) co pozwoli np. wbudować mu test (walidację). W dowolnym momencie obiekt taki można „podmienić” na obiekt statusowy zgodny z omówioną na początku Maszyna stanową, wtedy „obciążymy” bazowy obiekt biznesowy wiedzą o jego dopuszczalnych statusach.
Na zakończenie biznesowo
Systemy zarządzania przepływem dokumentów, przepływem pracy lub szumnie nazywane (i na wyrost) sytemami zarządzania procesami biznesowymi, sprawiają wiele problemów. Zaryzykuje tezę, że ich wdrażanie jest ryzykiem nie mniejszym niż wdrażanie systemów CRM (podobno tu odsetek przekroczonych budżetów i terminów przekracza 90%).
Nawet jeżeli ktoś przeprowadzi rzetelną analizę potrzeb i tak dostosuje (zaprojektuje i wytworzy) wdrażany system, że będzie spełniał pierwotne wymagania, okazuje się nie raz, że jego „życie” jest bardzo kosztowne. Problem tkwi w modelu zjawiska jakim jest przepływ pracy. Nie raz wielu z Państwa (mających takie systemy) słyszało po wdrożeniu, że coś wymaga wiele pracy albo jest wręcz nie możliwe już po rozpoczęciu eksploatacji systemu. Albo, że „proces może obsłużyć tylko jeden dokument” i złączenie w jeden kontrolowany bieg wypadków czegoś takiego jak opracowanie oferty w odpowiedzi na przyjęte zapytanie jest niemożliwe albo wymaga „sztucznego połączenia dwóch procesów w jeden” (czyli dwóch dokumentów Zapytanie i Oferta w jeden ciąg). Inny przypadek to „nie da się dowolnie zmieniać statusów dokumentów, proszę określić dokładnie jakie statusy będzie miał dokument oraz kiedy i jak będą się one zmieniały”.
Specyfikacja w postaci listy wymagań funkcjonalnych i niefunkcjonalnych niestety nie chroni przed ryzykiem kosztownych zmian w przyszłości. Jedynym wyjściem jest wyspecyfikowanie w dokumencie wymagań szczegółów logiki biznesowej w postaci projektu (modelu struktury wzorca) jakiego oczekujemy od dostawcy.
Wiele dokumentów analiz zawiera statyczne tabele dopuszczalnych stanów obiektów implementowane „na żywca” czyli wprost, ich zmiana wymaga pracy programisty. W efekcie system jest bardzo kosztowny w samym posiadaniu i korzystaniu z niego, a jak wiemy środowisko biznesowe jest zmienne. Środowisko dokumentów biznesowych jest szczególnie zmienne. Tu wymaganie (dokument wymagań) nie może stanowić tablicy (skończonej listy) dopuszczalnych statusów, czego nie raz żąda wielu dostawców oprogramowania.
To są skutki stosowania (często) wzorca State Machine do budowy systemów wspomagający przepływ pracy. Wzorzec ten jest często stosowany w systemach ERP do kontroli pojedynczych dokumentów ale moim zdaniem kompletnie nie nadaje się do implementacji systemów zarządzających przepływem pracy. To nie jest przypadek, że wielu dostawców systemów ERP zaleca jednak integrację z jakimś „dobrym workflow” zamiast bardzo kosztownej kastomizacji (o tym już tu nie raz pisałem).
Co z tym zrobić? Kupujący nie ma możliwości sprawdzenia wnętrza programu (tego jak zostało zaprojektowane) jeżeli kupuje gotowe. Musi bardzo „inteligentnie” stawiać wymagania na oprogramowanie by wychwycić wady jego projektu mogące wywołać lawinę kosztów podczas „zwykłego używania”. Jeżeli zapada decyzja o projekcie dedykowanym warto pokusić się o dobrego analityka i projektanta.
A co gdy kupujemy sami i gotowe? Proponuję np. umieszczenie w specyfikacji wymagań zgodności z wzorcem (metamodelem) WfMC oraz wymaganie możliwości pracy (dekretu) ad-hoc, a potem sprawdzać czy nas nie oszukano… Ale zwracam uwagę na ryzyko, że nie ma prostej zasady „zawsze taki wzorzec” …
Temat ten porusze także na konferencji GigaCon EOIF:
P.S.
Do czytających to programistów: jak znajdziecie jakieś uchybienie – proszę o litość
i wskazanie błędów w postaci komentarzy





16 Responses to Problem z wzorcem State Machine czyli ile Cię kosztuje workflow