Z pojęciem analizy wymagań spotykam się regularnie, co chyba w moim przypadku nie jest zaskoczeniem :). Jednak jest pewien niuans, który można wychwycić analizując takie analizy wymagań, a także słuchając opowiadań o przygodach programistów.
Miałem niedawno kolejny audyt dokumentacji wymagań opracowanej samodzielnie przez zamawiającego. Była duża i trudna w „odbiorze”, kilka osób z tej firmy spisało, każda dla swojego działu i ze swojej perspektywy, oczekiwania. Uporządkowali to tematycznie. Te kilka osób, plus ich podwładni, pracowali nad tym trzy miesiące (mimo, że nie „full time” to jednak sugeruje sobie samemu oszacować koszt tej pracy). Dokument w pierwotnej wersji praktycznie nie był przydatny. Drugim powodem napisania tego artykuły była dyskusja na pewnym forum na temat kompetencji w IT, ale o tym na końcu.
Praktycznie zawsze specyfikacja wymagań wykonana samodzielnie przez zamawiającego, to tak na prawdę opis tego czego sobie życzy na bazie swoich dotychczasowych doświadczeń. Regułą w takich przypadkach w zasadzie jest to, że „nowy system” to „coś lepszego od tego co mamy teraz”. Specyfikacja wymagań (jej treść) sprowadza się do listy poprawek i nowych żądań. Jeżeli wymagania zostały opracowane jako zapis wywiadów lub ankiet przez tak zwanego „analityka” z zewnątrz (pracownik dostawcy oprogramowania, niezależny analityk), efekty są praktycznie takie same (pomijam tu formę ich udokumentowania).
Zacytuje po raz kolejny metaforę z książki Martina Fowlera:
Wyobraźmy sobie kogoś, kto chce napisać program symulujący grę w snookera. Problem ten może zostać opisany przypadkami użycia opisującymi powierzchownie cechę: ?Gracz uderza biała kulę, która przemieszcza się z pewną prędkością, ta po określonym czasie uderza czerwoną kulę pod określonym kątem, uderzona czerwona kula przemieszcza się na pewna odległość w pewnym kierunku.? Możesz sfilmować setki tysięcy takich uderzeń, zarejestrować parametry każdego uderzenia i jego skutki. Jednak tą metodą i tak nie stworzysz nawet dość dobrej symulacji.
Jak nie trudno się domyśleć analiza wymagań nie może trwać w nieskończoność, powstanie mało takich opisów scenariuszy czyli opis mocno niekompletny. Zapis wywiadów, obserwacje, ankiety i poprzestanie na nich, nie mają prawa się sprawdzić bo w skończonym czasie na analizę zawsze będzie ich za mało a i tak będą chaotyczne (będzie to tylko część tego co może się wydarzyć i nie wiadomo, ile to procent całości bo nie znamy wszystkich).
Przypadki użycia same w sobie, stanowią bardzo mierne przybliżenie rzeczywistości. Oddanie programu do użytku, realizującego tylko ?konkretne scenariusze? i to w sposób ?obmyślony? przez programistę, który nie potrafi grać w snookera a tylko słyszał od gracza jak się to robi, najpewniej skończy się zabawą w kolejne iteracje, prototypy itp. Taki program będzie coraz lepszy ale nadal nie dotknie nawet realizmu snookera (więcej o tym tu Czy wymagania opisują tylko to ?co? system ma robić?).
Fowler pisze:
Aby napisać na prawdę dobrą grę, powinieneś raczej zrozumieć prawa rządzące ruchem kul, ich zależność od siły i kierunku uderzenia, kierunku itp. Zrozumienie tych praw pozwoli Ci znacznie łatwiej napisać dobre oprogramowanie.
I tu jest sedno: analiza nie powinna być tylko pasmem wywiadów, którego produktem będę setki stron zapisów z ankiet i przeprowadzonych rozmów. Analiza, to duża praca, której celem powinno być zrozumienie a nie tylko opisanie.
Jaka jest różnica? Produktem analizy, czyli zrozumienia zjawiska (pracy firmy itp.) jest model jej logiki działania (logika biznesowa), ten model – poprawny – pozwala przewidywać co nas czeka (testowany jest na poprawność losowo wybranymi zdarzeniami w firmie). Ten model to model dziedziny systemu (model logiki biznesowej: specyfikacja reguł biznesowych). Produktem wywiadów jest niestety wyłącznie opis skutków w reakcji na bodźce (np. przypadki użycia) ale nadal niezrozumiałe jest to „dlaczego akurat takie” skutki.
Wszystko to co nas otacza, samo w sobie jest naturalnie proste. Złożone są, nie poszczególne rzeczy, a to, że jest ich wiele i mają na siebie wzajemny wpływ. Celem analizy jest zidentyfikowanie w naszym otoczeniu tych prostych elementarnych rzeczy i zrozumienie ich wzajemnego na siebie wpływu. Zrozumienie to manifestuje się w postaci umiejętności stworzenia modelu tych współistniejących prostych rzeczy, zrozumienia i opisania ich cech i reguł wzajemnego oddziaływania. Jeżeli tym analizowanym środowiskiem jest organizacja, powstanie jej model, wiedza o tym jak funkcjonuje. A gdzie tu jest miejsce na oprogramowanie? By powstało, należy stworzyć także i jego model, by zrozumieć i opisać to czego potrzebujmy. Pamiętajmy, że jedna z najtrudniejszych gier na świecie ? szachy ? to tylko kilkanaście figur i proste reguły ich przemieszczania. Nawet największa organizacja to tylko skończona liczba ról i reguł ich postępowania. Należy je tylko odkryć. (żr. Jarosław Żeliński, referat na konferencji: Firma IT-Consulting Jarosław Żeliński – analityk biznesowy).
Nie krytykuje idei stosowania przypadków użycia, sam je stosuję. One jednak są konkretnymi, planowanymi przypadkami użycia oprogramowania, to minimalny zestaw opcji w menu – wymagane „teraz” usługi systemu. To nie ma jednak nic wspólnego z wewnętrzną budową oprogramowania, ta powinna modelować zastaną rzeczywistość.
Istnieje coś takiego jak zasada SOLID projektowania oprogramowania (jedna z kluczowych cech dobrych projektów oprogramowania). Cóż to jest SOLID? To rozwinięcie od ang. Single responsibility, Open-closed, Liskov substitution, Interface segregation and Dependency inversion (więcej na stronie SOLID (object-oriented design) – Wikipedia, the free encyclopedia).
Dzisiaj tylko o skutkach zaniedbania jednej, kluczowej chyba własności, która dotyczy całej aplikacji: Open-Close, która oznacza: aplikacja powinna być zamknięta na zmiany i otwarta na rozbudowę. Dla wielu na początku ta zasada brzmi wręcz kuriozalnie ale ona jak najbardziej jest możliwa do realizacji. Proszę zwrócić uwagę, że takie własnie są dobrze zarządzane firmy, nie ma w nich rewolucji organizacyjnej co roku, one się rozwijają a nie zmieniają.
Oprogramowanie, jeżeli w wyniku analizy wymagań opracowano nie tylko raport z wywiadów ale także model logiki działania, też spełni te zasadę. Czym grozi jej niespełnienie w stosunku do oprogramowania? A tym, do czego przyznał się jeden z programistów podczas pewnej dyskusji na forum:
kilka razy doświadczyłem sytuacji, że aby spełnić nowe proste wymaganie trzeba było się namęczyć zarówno z modelem danych jak i aplikacją, Oczywiście można w takiej sytuacji zarzucić, że system był źle zaprojektowany, nieskalowalny, nie przestrzegał SOLIDów, nie korzystał z wzorców itd ale to już jest inna bajka.
Na co ja odpowiedziałem: nie, to jest właśnie ta bajka o nazwie analiza wymagań i projektowanie, które powinny być zrozumieniem a nie tylko stenogramem. Wtedy nowe funkcjonalności oprogramowania można dodawać bez potrzeby przebudowy jego wewnętrznej struktury. Nie raz jest z powodu tych kosztów po protu niemożliwy jest rozwój systemu. Oceńcie teraz Państwo sami, Ci którzy tego doświadczyli, skutki wdrożenia np. systemu ERP z kastomizacją…. niestety ogromna większość tego oprogramowania nie spełnia zasady SOLID. Dlaczego? Bo model relacyjny baz danych, jeżeli obejmuje wszystkie dane systemu, niestety nie spełnia tej zasady z założenia. A dostawcy tych systemów wręcz cieszą się z tego reklamując się: „nasz system jest w pełni zintegrowany poprzez pracę na wspólnej bazie danych”…. Jak to przeczytasz, nie kupuj tego…
Pracując z wieloma zespołami programistycznymi zauważyłem, że problem z SOLID (na poziomie developmentu) polega zwykle (choć nie zawsze) na tym, że SOLID wydaje się zbyt prosty. Często jest wręcz strywializowany do poziomu składni.
Natomiast zasady te można stosować na poziomie modelu domenowego, arch. aplikacji i systemowej z wykorzystaniem porządnych frameworków, które wspierają solid na różnych poziomach i na różne sposoby.
Można osiągnąć na prawdę dużą giętkość niewielkim narzutem. Są tylko dwa warunki: znajomość technik oraz wiedza o tym, gdzie ta giętkość występuje i gdzie jest opłacalna (czyli dobre rozumienie problemu dziedzinowego)…
Hm… jeżeli ktoś uważa, że SOLID jest prosty to podziwiam :), bo opracowanie projektu, w którym np. rozbudowa prostego magazynu ilościowego do poziomu magazynu operującego egzemplarzem nie jest trywialne :). Chyba kluczem jest ostatnie Twoje zdanie :).
Osobiście wychodzę z założenia, że skoro świat się rozwija a nie cyklicznie wymienia na nowy, to trzeba szukać zrozumienia tego…:) i zrobić właściwy model.
Kluczem jest zrozumienie zasad SOLID już na poziomie konceptualnym, w całkowitym oderwaniu od frameworków, kodu i tym podobnych bebechów. Zespół który zna i rozumie podstawowe prawidła gry będzie instynktownie dokonywał dobrych wyborów, wiedząc jak negatywne konsekwencje niesie za sobą złamanie zasad.
Dużym problemem jest to, że kara za złamanie zasad nie jest obligatoryjna i jest odroczona w czasie. Za zwykły błąd składni IDE lub kompilator ukarze nas natychmiastowo. W przypadku gwałtu na zasadach SOLID, kary możemy spodziewać się po kilku miesiącach lub wcale.
Piszesz o giętkości, ale nawet najlepsze zrozumienie problemu dziedzinowego nie zastąpi szklanej kuli. Nie jesteśmy w stanie przewidzieć przyszłości, więc większość z tych giętkich miejsc pozostanie bezużyteczna, zwiększając tylko balast, który dźwigać muszą kolejne pokolenia programistów zanurzających się w projekt.
Dla mnie giętkość to wynaturzona interpretacja zasady otwarte-zamknięte, co zwykle kończy się tym, że mamy na utrzymaniu mnóstwo kodu typu boilerplate, fabryk i interfejsów z jedną implementacją. Czas poświęcony na myślenie o giętkości lepiej spożytkować na myślenie o prostocie. Prostota nas wyzwoli, umożliwi bezbolesne dodanie giętkości, jeśli tylko w przyszłości będzie taka potrzeba.
hmm, skąd mam taki dziwny avatar? :)))
Zmieniłem duże [G] na losowo dobierane monstery :), zdjęcia się pojawiają gdy ktoś ma profil na Gravatarze 🙂 (rozpoznawanie odbywa się po adresie email).
Pisząc „zbyt prosty” nie miałem na myśli, że jest powiedzmy uważany pogardliwie za prostacki. Chodziło mi o to, że jest interpretowany z naiwnym założeniem „aaa, to proste, my to mamy przecież, są interfejsy”.
Też coś podobnego miałem na myśli :), wielu programistów traktuje SOLID w zupełnym oderwaniu o modelowanej rzeczywistości i to postrzegam za błąd, bo zapominają, że poszczególne klasy to odwzorowania rzeczywistości a nie tylko „podział kodu na jakieś fragmenty”…