Jak nie tracić czasu na poszukiwanie rozwiązań, które są niepotrzebne?

Czas jest jednym z najcenniejszych zasobów szefa projektu. Presja czasu wytwarzana poprzez dążenie do szybkiego osiągnięcia spektakularnego sukcesu, jakiego potrzebują sponsorzy projektu, wymusza działania w dużym stopniu ukierunkowane na napisanie działającego kodu. Jak więc realizując projekt nie tracić czasu na poszukiwanie rozwiązań, które nikomu nie będą potrzebne?

Czas jest jednym z najcenniejszych zasobów szefa projektu. Presja czasu wytwarzana poprzez dążenie do szybkiego osiągnięcia spektakularnego sukcesu, jakiego potrzebują sponsorzy projektu, wymusza działania w dużym stopniu ukierunkowane na napisanie działającego kodu. Jak więc realizując projekt nie tracić czasu na poszukiwanie rozwiązań, które nikomu nie będą potrzebne?

Zbyt często zlecając zadanie do realizacji stawiamy jedynie wymóg, by produkt powstał. Znacznie rzadziej zdarza się nam definiować cechy tego produktu (poza tymi, które są niezbędne), a niezmiernie rzadko jesteśmy w stanie zdefiniować miary, jakimi ma się on charakteryzować. Często sytuacja taka wynika z faktu, że nie wiemy, czego chcemy (czy też raczej nasz klient nie wie, czego chce). Nasze oczekiwania będą się dopiero krystalizować w miarę powstawania kolejnych formatek ekranowych i implementacji kolejnych algorytmów. To sytuacja normalna: wizja produktu, jego definicja i kryteria jego oceny muszą mieć czas, aby się skrystalizować. Niestety, o tym procesie dojrzewania wizji produktu często zapominamy podczas planowania i zlecania nad nim prac.

W swoich działaniach kierownik projektu zbyt często zatraca pierwotny cel, dla którego zostały one podjęte. Zbyt łatwo przychodzi mu przeformułowanie celów. Tymczasem produkt budowany pierwotnie do innych potrzeb nie da się w krótkim czasie przebudować tak, by spełniał nowe wymagania i służył nowo postawionym celom. Skąd zatem ta zmienność? Sądzę, że w wielu przypadkach prace nad produktem software'owym podejmowane są zbyt wcześnie. W rzeczywistości wiele prac, które traktuje się jako działania nad końcowym produktem, są rozgrzewką. W początkowym okresie budowy systemu powinno się wykonywać więcej prac o charakterze studialnym. Zbyt rzadko sięgamy po opracowanie studium wykonalności, niezbyt często też decydujemy się na wykonanie prototypów.

Przeformułowanie celów, dla których buduje się dany system czy też jego część, już w trakcie projektu wynika najczęściej z braku odpowiednio dojrzałego procesu definiowania produktu, jego celów i miar w początkowym okresie.

Prototyp czy dalszy ciąg

Spostrzegam też częste zjawisko zatracania granic pomiędzy prototypowaniem a przyrostowym budowaniem systemu. Prototypowanie nie zakłada użycia produktu do rzeczywistego przetwarzania. Celem prototypu jest zebranie wymagań lub potwierdzenie już zebranych wymagań funkcjonalnych, weryfikacja algorytmów i ich wydajności albo uszczegółowienie wymagań. Może też nim być co innego, ale z pewnością celem prototypu nie jest jego eksploatacja w docelowym środowisku na rzeczywistych danych. Ponieważ nie jest to celem prototypu, to w trakcie jego powstawania nie wykonuje się wielu czynności, które powinny towarzyszyć wytwarzaniu wersji eksploatacyjnej. Nie dokumentuje się rozwiązań projektowych - dokumentacja pozostaje zazwyczaj w głowach ich twórców. Nie poddaje się prototypu regularnym testom - autorzy najczęściej zadowalają się tym, że działa. Nie produkuje się dokumentacji technicznej, nie wersjonuje poszczególnych komponentów, nie wykonuje wielu czynności inżynierskich, które powinny być wykonywane podczas produkcji oprogramowania. Dlaczego? Gdyż cel tego działania to prototyp, a nie gotowy do eksploatacji produkt. Nadchodzi jednak taki dzień, w którym szef inaczej formułuje cel prac i decyduje się na rozwój prototypu w kierunku wersji eksploatacyjnej. I tak prowizorka staje się produktem, a skądinąd słuszna koncepcja szybkiego budowania aplikacji (RAD) staje się (niesłusznie) uzasadnieniem do zaniechania wykonywania koniecznych i potrzebnych czynności inżynierskich. Nic bardziej zgubnego.

Walka z czasem i wychodzenie naprzeciw oczekiwaniom sponsorów projektu powinny być realizowane poprzez przyrostową budowę systemu. W przeciwieństwie do prototypowania zakłada ona wykonanie pełnego cyklu produkcyjnego dla wybranego, ograniczonego zakresu funkcjonalnego. Osiągnięcie pełnej funkcjonalności odbywa się poprzez wykonanie kilku kolejnych przyrostów. Jak jednak przekonać klienta do takiego podejś-cia? Jak nakłonić go do odsunięcia w czasie momentu, kiedy cały system zadziała? Rozwiązaniem problemu jest dyskusja nad hierarchią celów, jakim ma służyć uruchamiany system. W wielu przypadkach z pomocą przychodzi zewnętrznie narzucona data uruchomienia systemu, która w naturalny sposób wymusza gradację celów, ustalenie priorytetów i wag dla poszczególnych funkcji systemu.

Nieograniczone możliwości

Dostępne dzisiaj narzędzia powodują, że spektrum możliwych rozwiązań, jakie projektant czy programista mogą zaoferować, jest praktycznie nieograniczone. Inwencja twórcza i chęć samorealizacji każdego z członków zespołu staje się - z jednej strony - siłą napędową rozwoju systemu, z drugiej zaś - jest dużym zagrożeniem dla otrzymania spójnego produktu, o zadanych cechach w oczekiwanym czasie. Niestety, osobiste zadowolenie członka zespołu realizującego dany produkt nie musi przekładać się na sukces tego produktu. Wielu z nas z pewnością zgodzi się z potoczną opinią, według której, jeśli dasz programiście do wykonania fragment oprogramowania, to możesz być pewien, że skomplikuje go tak bardzo, jak to możliwe. Skąd takie działania? Uważam, iż wynika to z braku jasno określonych celów i kryteriów odbioru bądź z obawy, że jeśli nawet zostały one sformułowane, to istnieje - w ocenie programisty - szansa, iż wkrótce zostaną zmienione. Programista więc, nauczony doświadczeniem z niejednego już projektu, od razu wbudowuje w kod dziesiątki przeróżnych definicji, słowników, parametrów i innych tego rodzaju wodotrysków, byleby dzisiaj zabezpieczyć się przed zmianami w kodzie oprogramowania, których spodziewa się w przyszłości. Uwaga ta dotyczy nie tylko programistów, ale i projektantów. Dobrą praktyką w takich sytuacjach jest specyfikowanie nie tylko pożądanych cech produktu, ale również jawne określenie, czego produkt nie powinien zawierać (np. nie powinien być definiowalny).

W powodzi wszechstronności

Zbyt dużo wokół nas produktów, które "obierają, myją, gotują i podają do stołu". Przed kilkoma laty w jednym z banków uruchamiałem moduł kredytowy. Po stronie klienta został wyznaczony zespół odpowiedzialny za jego wdrożenie, na którego czele stały dwie starsze panie. Ponieważ jawnie deklarowały one swoje wielkie zadowolenie z uruchamianego systemu informatycznego i głośno wszystkim zachwalały wprowadzane w związku z tym zmiany, nie miałem większych obaw co do powodzenia procesu. Wkrótce jednak okazało się, że wyobrażenie tych pań o systemie komputerowym jest - rzec można - bajkowe. W ich wyobrażeniach komputer mógł wszystko i bez ograniczeń. Przecież komputery drukują, liczą, mogą zapamiętywać dowolne informacje i oferować do nich szybki dostęp. Dlaczego więc tutaj nie można pamiętać wniosków kredytowych, dokonywać ich analizy w połączeniu z historią kredytów już udzielonych danemu klientowi, na tej podstawie przyznawać nowy kredyt, który następnie będzie monitorowany, a w przypadku stwierdzenia dowolnej nieprawidłowości w jego obsłudze będzie podejmowana odpowiednia, zdefiniowana w regulaminie kredytowym akcja - czy to dodatkowe naliczenie odsetek, czy to wysłanie korespondencji. A wszystko automatycznie i bez udziału człowieka. Byliśmy o krok od konieczności wykonania programu, który potrafiłby wszystko, czyli zapewne nic. Na szczęście pomysł upadł, kiedy - nie wdając się w ogóle w rozważania na temat sensowności jego realizacji - zacząłem wyjaśniać paniom, jakie dane testowe będą musiały przygotować, aby zweryfikować poprawność opracowanego przez nas programu. Jak to było: "Wszystko jest możliwe, pod warunkiem że nie ja to muszę wykonać".

Odnoszę wrażenie, że wiele naszych systemów jest "przekombinowanych", a wiele z wymagań stawianych przez użytkowników jest "na wyrost". Wszystkich, którzy zamawiają systemy informatyczne, chciałbym przekonać, iż proste jest piękne, a czasami bywa wręcz genialne. Budując oprogramowanie, bardzo rzadko korzystamy ze świadomego wartościowania celów i stojącej za tym hierarchii wymagań. Klient często obawia się, że wymagania o niskim priorytecie zostaną zignorowane lub będą zawsze mniej ważne od innych, w efekcie czego nigdy nie zostaną zrealizowane. Pośrednim tego skutkiem może być definiowanie "barokowych" wymagań, gdzie w miejsce jasnych i prostych opisów funkcjonalności pojawiają się oczekiwania rozwiązań, które "obierają, myją, gotują i podają do stołu". Stosunkowo rzadko mamy do czynienia z sytuacją, w której możemy uchwycić prostą relację pomiędzy postawionym wymaganiem a kosztami jego realizacji, co również nie sprzyja prostocie systemów. Natomiast tym, którzy realizują postawione wymagania, chciałbym przypomnieć starą rzymską dewizę: "Dziel i rządź". Radzenie sobie z małymi kawałkami jest łatwe, proste i przyjemne. Zmaganie się z wielkimi problemami zawsze będzie żmudne, trudne i kłopotliwe.

Wszystkim zapewne doskonale znane są statystyki, które uwidoczniają, ile kosztuje nas usunięcie błędu projektowego dostrzeżonego w początkowej fazie wytwarzania oprogramowania, a ile usunięcie tego samego błędu, gdy zostanie on zauważony w końcowych etapach produkcji. Wiemy, że z etapu na etap koszt ten wzrasta o rząd wielkości. Dlaczego więc wciąż tak mało skutecznie działamy w obszarze zbierania wymagań na system i definiowania kryteriów jego oceny? Pytanie pozostawiam bez odpowiedzi.

Włodzimierz Serwiński jest pracownikiem Prokom Software SA, kierownikiem projektu KSI ZUS

W celu komercyjnej reprodukcji treści Computerworld należy zakupić licencję. Skontaktuj się z naszym partnerem, YGS Group, pod adresem [email protected]

TOP 200