2. Cykle wytwarzania oprogramowania

Jak pokazaliśmy w poprzednim rozdziale, zakończenie projektu informatycznego sukcesem nie jest łatwym zadaniem. Wytwarzanie oprogramowania można jednakże przedstawić jako powtarzalny cykl rozwiązywania poszczególnych problemów, prac technicznych i łączenia rozwiązań. Na podstawie doświadczeń zebranych na przestrzeni lat opracowano wiele modeli procesów wytwórczych oprogramowania, które przedstawiają różne cykle wytwarzania oprogramowania.

2.1. Dyscypliny cyklu wytwarzania oprogramowania

W procesie wytwarzania oprogramowania powstaje przede wszystkim system oprogramowania. Oprócz tego, w trakcie projektu konieczne jest wytworzenie innych produktów, takich jak instrukcja użytkownika, specyfikacja wymagań, dokumentacja projektowa, itd. Takie produkty uzupełniające (zwane także pośrednimi) powstają w wyniku różnych działań, które możemy podzielić na grupy nazywane dyscyplinami. Dyscyplina inżynierii wymagań stanowi spójny zestaw czynności, które są powiązane z zasadniczym obszarem działania w ramach projektu konstrukcji oprogramowania. Należy jednak zwrócić uwagę na to, że podział na dyscypliny nie oznacza podziału na etapy, czyli nie decyduje o uporządkowaniu czasowym wykonywania zadań w poszczególnych dyscyplinach.

Dyscyplina wymagań

W ramach dyscypliny wymagań powinniśmy w pierwszej kolejności zidentyfikować problemy, które może rozwiązać system oprogramowania, a także podjąć decyzję o budowie takiego systemu. Podstawą określenia potrzeb klienta wynikających z zadanego problemu jest specyfikacja wymagań. Głównym celem specyfikacji wymagań jest określenie zakresu i kształtu przyszłego systemu, który będzie realizował potrzeby klienta. W ramach proponowanego przez nas podziału, dyscyplina ta dzieli się na dwie zasadnicze dyscypliny składowe – analizę środowiska (np. biznesu) oraz analizę wymagań.

W ramach analizy środowiska opisujemy aktualny oraz docelowy stan środowiska (biznesu). Wykonywane jest to przy współpracy przedstawicieli klienta (osób zamawiających system lub ich reprezentantów).

Opis środowiska (biznesu) stanowi pierwszy zasadniczy produkt dyscypliny wymagań. Jest on opisem fragmentu świata, który jest obszarem działań danej organizacji wraz ze środowiskiem, w jakim ta organizacja (biznes) działa. Formułowanie takiego opisu polega na stworzeniu precyzyjnego i zrozumiałego modelu, który zawiera wszystkie elementy środowiska (biznesowego) oraz zasady oddziaływania ich na siebie. Model może opisywać tylko stan docelowy (po zbudowaniu systemu informatycznego), lub być uzupełniony o opis stanu aktualnego.

Kompletna specyfikacja wymagań wynika bezpośrednio z opisu biznesu i można ją porównać do piramidy. Na samym szczycie znajduje się wizja systemu, która dostarcza informacji na temat ogólnych cech systemu w ścisłym powiązaniu z potrzebami biznesowymi klienta. Zakres sytemu wyznaczają wymagania użytkownika w postaci uporządkowanego zbioru cech i funkcji systemu, które powinny być podstawą do zawarcia kontraktu. Wizja systemu i wymagania użytkownika tworzą wymagania zamawiającego, które są odzwierciedleniem rzeczywistych potrzeb zdefiniowanych przez biznes. Na najniższym poziomie piramidy są wymagania oprogramowania, które opisują szczegóły funkcjonalne komunikacji między użytkownikami i systemem, wszystkie wymieniane między nimi dane oraz planowany wygląd systemu.

Dyscyplina projektowania

W ramach dyscypliny projektowania dokonujemy syntezy problemu opisanego w ramach dyscypliny wymagań poprzez opracowanie „planów projektowych” dla systemu. Celem działań tej dyscypliny jest stworzenie modeli projektowych na różnych poziomach abstrakcji, na podstawie których zostanie zaimplementowany system.

Mając do dyspozycji opis środowiska biznesu i specyfikację wymagań można zdefiniować, jakich elementów fizycznych (np. serwer bazy danych, serwer aplikacyjny, maszyny klienckie, urządzenia mobilne) będzie potrzebował budowany system i w jaki sposób te elementy będą się ze sobą komunikować. Jest to najbardziej ogólny, fizyczny model architektoniczny. Nie definiuje on logiki działania systemu, która definiowana jest na poziomie architektury logicznej. Na tym poziomie definiuje się moduły wykonawcze (komponenty), z jakich będzie się składał budowany system oraz powiązania komunikacyjne (np. interfejsy) między tymi modułami.  Interfejsy, które są specyfikacją funkcji udostępnianych przez komponenty architektoniczne, pozwalają traktować moduły jako czarne skrzynki. Na tym poziomie abstrakcji nie skupiamy się na tym,  „co jest w środku” komponentów. Skupiamy się na tym, jakie funkcje komponenty spełniają.

Istotnym elementem modelu architektonicznego i zależnych od niego modeli szczegółowych są struktury danych, które służą do komunikacji poprzez interfejsy. Na podstawie słownika możemy zdefiniować tzw. obiekty transferu danych (ang. Data Transfer Object). Określają one „paczki danych”, które mogą być przesyłane między poszczególnymi komponentami systemu.

Kolejnym poziomem projektowania jest stworzenie szczegółowych projektów modułów. Na tym poziomie definiujemy konkretne szczegóły „czarnych skrzynek”. Dokładnie przedstawiamy strukturę oraz opracowujemy sekwencje wykonywanych operacji, których celem jest realizacja funkcji określonych w poszczególnych interfejsach komponentów.

Produktem projektowania jest zbiór spójnych modeli, które dostarczą szczegółowych informacji o składnikach systemu, który ma spełniać wymagania opisane w specyfikacji wymagań i funkcjonować w opisanym środowisku.

Dyscyplina implementacji

W wyniku działań objętych dyscypliną implementacji zostaje wytworzony kod (program) realizujący wymagania zdefiniowane podczas analizy i spełniający założenia projektowe, określone w modelach projektowych. Do wytworzenia działającego systemu wykorzystuje się zbiór technologii, które są zgodne z wymaganiami technicznymi i wpisują się w środowisko działania budowanego systemu.

Proces programowania wymaga odpowiedniego środowiska i organizacji pracy. Aby stworzyć system, który będzie prawidłowo funkcjonował w środowisku produkcyjnym klienta, należy takie środowisko zbudować również w wersji testowej (implementacyjnej). Duży wpływ na kształt środowiska implementacyjnego mają wymagania jakościowe i ograniczenia środowiska biznesowego.

Implementacja systemu oznacza implementację poszczególnych modułów (komponentów) zaprojektowanych w ramach dyscypliny projektowania. Każdy moduł może być realizowany niezależnie od pozostałych (przez różnych programistów), ale powinien poprawnie z nimi współdziałać.

Pożądaną cechą kodów źródłowych, oprócz oczywistej zgodności z modelami projektowymi i wymaganiami, powinny być: wspólna konwencja programistyczna, dobra dokumentacja i gwarancja poprawności działania potwierdzona dokumentacją testów jednostkowych.

Po implementacji sprawnie działających (przetestowanych) modułów i ich połączeniu, całość powinna przejść testy integracyjne. Tak sprawdzony kod systemu jest głównym produktem dyscypliny implementacji.

Dyscyplina walidacji (testowania)

Celem testowania w ramach osobnej dyscypliny walidacji jest sprawdzenie, czy zbudowany system oprogramowania spełnia wymagania określone w specyfikacji wymagań i działa poprawnie w środowisku biznesowym.

W odróżnieniu od testów przeprowadzonych w czasie implementacji, głównymi odbiorcami testów w ramach walidacji są przedstawiciele zamawiającego. Zwykle są to przyszli użytkownicy systemu, wytypowani i specjalnie przygotowani do nadzorowania i wykonywania czynności związanych z testowaniem. Poza sprawdzeniem poprawności integracji, które dokonywane jest przez osoby odpowiedzialne za infrastrukturę informatyczną organizacji, sprawdzana jest również zgodność z wymaganiami zamawiającego oraz szczegółowymi wymaganiami oprogramowania. Ogół tego typu testów nazywamy testami akceptacyjnymi (ang. acceptance test), gdyż są one warunkiem akceptacji systemu przez klienta.

Przeprowadzenie testów akceptacyjnych systemu wymaga planu testów. Zazwyczaj plan testów jest dokumentem powstałym na podstawie specyfikacji wymagań. Poszczególne testy ułożone są w odpowiedniej kolejności, która pozwala na prawidłowe sprawdzenie prawidłowości działania poszczególnych funkcjonalności systemu. Testy takie przypominają instrukcje postępowania przygotowane dla użytkowników systemu. Rezultatem jest powstanie kompletnych scenariuszy testów. Efektem wykonania konkretnego scenariusza testów jest potwierdzenie poprawności działania lub opis błędu.

Wynikiem dyscypliny testowania jest dokumentacja testów akceptacyjnych, która jest podstawą do zatwierdzenia systemu i przejścia do czynności objętych dyscypliną wdrożenia.

Dyscyplina wdrożenia

Wdrożenie systemu polega zasadniczo na przeniesieniu systemu do warunków środowiska produkcyjnego i przekazaniu go do właściwego użytkowania. Dyscyplina wdrożenia obejmuje czynności związane z instalacją systemu oraz umożliwieniem korzystania z systemu przez jego użytkowników. Głównym produktem dyscypliny wdrożenia jest zainstalowany system, działający w docelowym środowisku wykonawczym. Innymi produktami są np. dokumentacja dla użytkowników oraz dokumentacja techniczna.

Można wyróżnić kilka najbardziej popularnych strategii wdrożenia nowego systemu do środowiska produkcyjnego:

- Wdrożenie bezpośrednie – nowy system zostaje wdrożony od razu w całości. Jest to strategia niosąca często spore ryzyko.

- Wdrożenie równolegle – obok nowego systemu, przez pewien czas działa również stary.

- Wdrożenie pilotażowe – w pierwszej fazie, fragment nowego systemu lub cały system zostaje uruchomiony w jednej z jednostek organizacyjnych. Dopiero po sprawdzeniu poprawności tego wdrożenia, system zostaje wdrożony w pozostałych jednostkach.

- Wdrożenie stopniowe – strategia polegająca na wprowadzaniu w działalność organizacji kolejnych fragmentów nowego systemu, uniezależniając pozostałe obszary działalności od nowego systemu.

Istotnym elementem dyscypliny wdrożenia jest przygotowanie materiałów dla użytkowników oraz przeprowadzenie szkoleń dla przyszłych użytkowników. Efektem pomyślnego wdrożenia systemu jest działający system, sprawnie używany przez jego użytkowników.

Dyscyplina konserwacji

Czynności konserwacji, zwane także czynnościami utrzymania, stanowią zawsze ostatni etap w cyklu życia oprogramowania. Obejmują one zapewnianie poprawnego funkcjonowanie systemu w środowisku biznesowym. W trakcie pracy z systemem oprogramowania mogą zostać wykryte wcześniej nieznane defekty. Wymagana funkcjonalność lub cechy jakościowe systemu oprogramowania, które zostały zdefiniowane w ramach analizy wymagań, mogą ulec zmianie już po oddaniu systemu do użytku. Może zmienić się także samo środowisko i procesy biznesowe.  Wszystkie te sytuacje wymuszają podjęcie pewnych działań, które można podzielić na cztery grupy:

-     czynności naprawcze obejmujące usuwanie defektów oprogramowania;

-     czynności adaptacyjne dostosowujące oprogramowanie do zmieniającego się środowiska;

-     czynności ulepszające wprowadzające nowe funkcjonalności i zmianę już istniejących;

-     czynności prewencyjne przygotowujące oprogramowanie do przyszłych modyfikacji.

W niektórych przypadkach wprowadzenie zmian w funkcjonującym systemie, może wymagać przejścia przez wszystkie dyscypliny, od wymagań do implementacji i wdrożenia.

2.2. Przegląd cykli wytwarzania oprogramowania

Przedstawione wyżej dyscypliny określają zakres czynności i produktów wykonywanych w typowym projekcie wytwarzania oprogramowania. Czynności te tworzą pewien ciąg, który powinien być wykonywany w określonej kolejności. Taki ciąg czynności nazywamy procesem wytwarzania oprogramowania. W dobrze zorganizowanym projekcie, proces ten przebiega zgodnie z dobrze określonym cyklem wytwórczym, który jest elementem całego cyklu życia oprogramowania. Cykl wytwórczy definiuje rozłożenie czynności z poszczególnych dyscyplin w czasie.

W większości współczesnych projektów stosuje się jeden z dwóch cykli wytwórczych: cykl wodospadowy (również nazywany kaskadowym) lub cykl iteracyjny. Cykle wytwórcze posiadają warianty, charakterystyczne dla różnych metodyk wytwórczych, które zostały opisane w kolejnym rozdziale. Cykl wytwórczy jest rodzajem przewodnika, który wskazuje kierunek, który należy obrać, aby osiągnąć zamierzony cel, ale nie pokazuje drogi, którą należy pójść. Szczegóły tej drogi w szczegółach określa natomiast metodyka.

Cykl wodospadowy

Koncepcja wodospadowego (ang. waterfall) cyklu życia oprogramowania, zwanego także kaskadowym lub klasycznym, została sformułowana już w roku 1970.  Główna ideą tego cyklu jest ujęcie dyscyplin wytwarzania oprogramowania w sekwencję dobrze wyodrębnionych kroków (faz lub etapów), które prowadzą do zbudowania systemu oprogramowania. Rysunek 2.1 przedstawia ogólny schemat cyklu wodospadowego. Kolejne etapy wykonywane są raz w trakcie trwania projektu i następują po sobie. Nazwa tego cyklu wynika z podobieństwa tego schematu do wodospadu lub kaskady.

Rysunek 2.1: Wodospadowy cykl wytwarzania oprogramowania

Jak wskazuje rysunek, poszczególne etapy „wodospadu” odpowiadają dyscyplinom cyklu życia oprogramowania przedstawionym w poprzedniej sekcji. Każdy etap dostarcza co najmniej jednego produktu, który podlega weryfikacji i akceptacji. Następny etap może się rozpocząć tylko po zakończeniu poprzedniego i wykorzystuje jego produkty jako punkt wyjścia. W praktyce jednak, sąsiadujące ze sobą etapy zazębiają się i przekazują nawzajem informacje. Oznacza to, że w ramach jednego etapu możemy wrócić do poprzedniego etapu (tzw. wodospad z nawrotami).

Cykl wodospadowy w naturalny sposób odzwierciedla proces rozwiązywania złożonych problemów. Wszystkie podejmowane czynności prowadzą od potrzeb użytkownika do gotowego systemu w jednym przebiegu przez poszczególne grupy czynności (dyscypliny). Umożliwia to łatwe zarządzanie zasobami (zespoły specjalistów, sprzęt). Przejście do kolejnych faz wymaga jednak zamrożenia wyników prac w fazach poprzednich. Wynika to z konieczności zachowania spójności produktów w ramach całego cyklu. Konieczność powrotu do poprzednich faz oznacza odejście od czystego cyklu wodospadowego.

Niestety, cykl wodospadowy posiada wady, które rodzą zasadnicze zagrożenia. Podstawowym problemem jest późna weryfikacja wyników prac. Problemy z realizacją wymagań klienta odkrywane są zazwyczaj dopiero w fazie testowania, a nawet dopiero w fazie wdrożenia. Zauważmy też, że istotnym czynnikiem jest tutaj subiektywizm oceny produktów. Na przykład, jakość specyfikacji wymagań możemy w pełni ocenić dopiero w fazie implementacji. Inną wadą cyklu wodospadowego jest niewielka elastyczność w radzeniu sobie ze zmianami (w tym – zmianami zakresu). Bardzo trudno jest stworzyć poprawną i kompletną specyfikację już na początku projektu. Rzeczywiste potrzeby klienta są często odkrywane lub zmieniane już w trakcie trwania prac nad systemem oprogramowania.

Wodospadowy cykl wytwarzania oprogramowania, mimo iż jest dosyć leciwy i posiada wiele wad, wciąż jest popularny. Powodzenie projektu realizowanego cyklem wodospadowym mocno zależy od stabilności i poprawności specyfikacji wymagań. Dlatego jest polecany do krótkich projektów, w których wymagania są dobrze określone i zrozumiałe, a ich specyfikacja jest w pełni przygotowana. W przypadku dłuższych projektów powinniśmy być pewni, że problem jest bardzo dobrze określony i nie będzie podlegał modyfikacjom.

Cykl iteracyjny

Podstawą dla stworzenia cyklu iteracyjnego była chęć eliminacji zagrożeń związanych z „zamrażaniem” produktów poszczególnych faz cyklu wodospadowego. Zagrożenia takie możemy wyeliminować przez wprowadzenie wielokrotnego przechodzenia przez powiązane ze sobą dyscypliny. To podejście jest główną cechą iteracyjnego cyklu wytwarzania oprogramowania. Ilustruje to rysunek 2.2.  Jak widzimy, cykl iteracyjny zachowuje podział na dyscypliny, ale czynności w ramach wszystkich dyscyplin wykonywane są wielokrotnie.

W projekcie planowane jest wiele iteracji, gdzie każda iteracja trwa zazwyczaj kilka tygodni (najczęściej od 2 do 6). Poszczególne iteracje rozpoczynają się od wyboru i wyspecyfikowania określonego zakresu wymagań, odpowiadającego przyrostowi funkcjonalności systemu. Następnie następują czynności syntetyzowania problemu – projektowanie, implementacja oraz testowane. Czynności te dotyczą zakresu wymagań wybranych do danej iteracji oraz ew. wymagań, które nie zostały prawidłowo zrealizowane w poprzednich iteracjach. Dokładnie testuje się funkcjonalność wykonaną w danej iteracji, a także przeprowadza się mniej dokładne testy funkcjonalności zrealizowanych wcześniej. Po zakończeniu testów i akceptacji ich wyników przechodzimy do kolejnej iteracji. W razie stwierdzenia błędów lub uwag kod klienta, odpowiednie zadania są przydzielane do kolejnych iteracji.

 

Rysunek 2.2: Iteracyjny cykl wytwarzania oprogramowania

Po zakończeniu pewnej liczby iteracji możliwe jest wdrożenie systemu. W niektórych projektach wdrożenie wykonywane jest tylko raz – po ostatniej iteracji. Najczęściej jednak planuje się wdrożenia pośrednie. Po ostatnim wdrożeniu następuje faza konserwacji, podobnie jak w cyklu wodospadowym.

Zastosowanie cyklu iteracyjnego nie daje oczywiście gwarancji na końcowy sukces procesu wytwórczego. Zwiększa jednak szanse na jego powodzenie, przy założeniu prawidłowego stosowania jego zasad. Wszelkie problemy odkrywane są po każdej iteracji. Jeżeli aktualny stan oprogramowania nie odpowiada rzeczywistym potrzebom, lub funkcjonalność nie została w pełni zrealizowana, możemy w naturalny sposób – zgodny z założeniami cyklu – przejść do fazy wymagań, a następnie do faz projektowania, implementacji i testowania.

Cykl iteracyjny pozwala na przyrostowe tworzenie systemu oprogramowania. Daje to możliwość ustalenia priorytetów dla określonych funkcjonalności systemu oraz kolejności ich wykonania i wdrożenia. Produkty poszczególnych faz nie muszą być zamrażane, przez co na koniec cyklu wytwarzania oprogramowania wszystkie specyfikacje i dokumentacje odpowiadają rzeczywistym warunkom.

Iteracyjny cykl wytwarzania oprogramowania najlepiej sprawdza się w projektach budowy średnich i dużych systemów oprogramowania, gdzie nie wszystkie wymagania są dobrze zdefiniowane, a nawet rozpoznane.