Podręcznik

1. Wprowadzenie do inżynierii oprogramowania

1.1. Co to jest inżynieria oprogramowania?

Inżynieria oprogramowania zajmuje się inżynierskim podejściem do tworzenia oprogramowania. Inżynieria oprogramowania dąży do ujęcia działań związanych z budową programów komputerowych w ramy typowe dla innych dziedzin inżynierii. W szczególności, inżynieria oprogramowania stosuje wiedzę naukową, techniczną oraz doświadczenie w celu projektowania, implementacji, walidacji i dokumentowania oprogramowania. Inżynierię oprogramowania można podzielić na kilka zasadniczych dyscyplin. Dyscypliny te związane są z typowymi etapami działań inżynierskich w dowolnej dziedzinie inżynierii.

Dyscyplina 1: Wymagania

Systemy informatyczne realizują coraz bardziej złożoną funkcjonalność dla coraz większej liczby grup użytkowników. Stąd też bardzo istotne jest uzyskanie od tychże użytkowników (jak również od innych grup zainteresowanych systemem) wszystkich niezbędnych informacji dotyczących ich potrzeb.

Dyscyplina 2: Projektowanie

System oprogramowania wymaga projektu. Niezbędne jest określenie przez architektów, z jakich składników będzie się składał system.

Dyscyplina 3: Implementacja

Wykonanie (implementacja) systemu oprogramowania wymaga zachowania zgodności z projektem. System oprogramowania konstruowany jest poprzez pisanie programów w odpowiednich językach programowania. W zachowaniu zgodności z projektem mogą pomóc odpowiednie metody przekształcania projektu w kod systemu.

Dyscyplina 4: Walidacja

W przypadku systemów oprogramowania, wykrycie usterek jest bardzo złożonym problemem. Wynika to przede wszystkim ze złożoności i zmienności wymagań oraz złożoności systemów. Przede wszystkim należy sprawdzić, czy system został zbudowany zgodnie z potrzebami klienta i użytkowników. Należy podkreślić, że walidacja nie powinna być wykonywana dopiero po zakończeniu implementacji. Należy ją przeprowadzać jak najwcześniej, w celu zmniejszenia ryzyka niepowodzenia.

Dyscyplina 5: Nadzór

W trakcie budowy systemu oprogramowania też bardzo istotne jest przestrzeganie pewnych procedur i reguł postępowania. W tym celu zostały opracowane odpowiednie standardowe metodyki. Odejście od przestrzegania (lub po prostu brak) metodyk jest bardzo częstą przyczyną niepowodzeń projektów, w które wkrada się chaos organizacyjny.

Dyscyplina 6: Środowisko pracy.

Budując system oprogramowania powinniśmy bardzo uważnie podejść do budowy środowiska pracy. Bardzo istotny jest wybór narzędzi wspomagających projektowanie systemu. Podczas budowy systemu, niezbędne jest posiadanie narzędzi umożliwiających zarządzanie złożonym kodem (dobre środowisko zintegrowane oraz narzędzia do zarządzania konfiguracją i zmianami). Dobrze dobrane środowisko pracy ułatwia również rozbudowę systemu (tzw. ewolucja systemu).

1.2. Podstawowe problemy inżynierii oprogramowania

Typowe współczesne systemy oprogramowania składają się z setek tysięcy lub nawet milionów wierszy kodu w różnych językach programowania. Jest oczywiste, że takiej liczby elementów nie jest w stanie opanować nawet najbardziej uzdolniony programista. Konieczne jest zatem zastosowanie metod opanowania tej złożoności.

Złożoność i różnorodność systemów oprogramowania rodzi wiele problemów, które trapią projekty konstrukcji takich systemów. Różnorodne problemy dotykające współczesne systemy oprogramowania prowadzą do wielu niepowodzeń w budowie tychże systemów.  Z punktu widzenia uczestników projektu budowy oprogramowania można wyróżnić trzy kryteria warunkujące powodzenie. Kryteria te najczęściej określane są na etapie zawierania umowy na budowę systemu. W takiej umowie określa się wymagania odnośnie systemu, termin oddania systemu do użytku i koszt jego wykonania. Zatem można uznać, że projekt skończył się sukcesem, jeżeli:

  • Projekt mieści się w budżecie,
  • Projekt mieści się w ramach czasowych (termin zakończenia nie jest przekroczony),
  • Dostarczony system spełnia rzeczywiste potrzeby klienta (zadowolony klient).

1.3. Przyczyny problemów

Jak wynika z badań i obserwacji, problemy nie dotyczą tylko pojedynczych projektów, ale całego przemysłu dostarczającego oprogramowanie. W roku 1967 można było ten stan – za konferencją NATO na temat inżynierii oprogramowania – nazwać kryzysem. Trwanie tego stanu do dzisiaj należy jednak – za Rogerem Pressmanem – nazwać chorobą chroniczną. Można też połączyć te określenia i nazwać je chronicznym kryzysem oprogramowania (Wyatt Gibbs – Software’s Chronic Crisis, Scientific American, 1994). O chroniczności tej sytuacji świadczy również to, że klasyczna książka Freda Brooksa („Mityczny osobo-miesiąc”, 1975 r.) pozostaje nadal aktualna i wymagała jedynie krótkiego uwspółcześnienia w swym wydaniu jubileuszowym (1995 r.).

Jak jest przyczyna tego „chronicznego kryzysu”? Na to pytanie w zasadzie odpowiedź jest jedna: z braku panowania nad wyjątkowo złożonym produktem, jakim jest system oprogramowania. Kluczowymi punktami są tutaj wymagania użytkowników, architektura i kontrola jakości. Wymagań użytkowników dla jednego systemu są zazwyczaj setki. Co więcej, są one sformułowane najczęściej przez odbiorców w taki sposób, że można na ich podstawie zbudować kilka całkowicie różnie działających systemów i nadal być z nimi zgodnym. Dlatego bardzo istotne jest wykonanie analizy wymagań precyzyjnie określającej sposób funkcjonowania systemu. Co więcej, ten opis powinien być zrozumiały nie tylko dla użytkowników i analityków, ale również dla projektantów i programistów.

Drugą przyczyną choroby oprogramowania jest architektura, a raczej jej brak. Architektura jest takim elementem projektu, który zapewnia realizację wymagań użytkownika, zapobiega „radosnej twórczości” programistów i znacznie redukuje złożoność tworzonych modeli. Wreszcie kontrola jakości. Często kojarzymy ją z testowaniem. Rzeczywiście – niedostateczne testowanie to częsty grzech firm produkujących oprogramowanie. Równie poważnym grzechem jest jednak niedostateczna kontrola satysfakcji użytkowników.

Problemy, przed którymi stoi inżynieria oprogramowania wynikają często z zaniechania stosowania ogólnych zasad inżynierii. Dlatego bardzo ważne jest, abyśmy zidentyfikowali przyczyny problemów i zaczęli je aktywnie pokonywać stosując zasady wiedzy inżynierskiej z zakresu inżynierii oprogramowania.

Poniżej przedstawimy główne przyczyny problemów projektów konstrukcji oprogramowania.

  1. Nieprecyzyjne specyfikowanie oprogramowania.
  2. Zła komunikacja.
  3. Brak projektowania architektonicznego.
  4. Brak zarządzania złożonością system.
  5. Bardzo późne odkrywanie poważnych nieporozumień.
  6. Brak zarządzania zmianami.
  7. Nieużywanie narzędzi wspomagających.

1.4. Najlepsze praktyki inżynierii oprogramowania

Coraz więcej organizacji wytwarzających oprogramowanie (chociaż nadal zdecydowanie zbyt mało) zaczyna stosować metody inżynierskie w produkcji oprogramowania. Jakie są zatem te metody? Jakie praktyki należy stosować, aby nie doświadczać symptomów „przewlekłej choroby”? Przedstawiamy tutaj zbiór najlepszych praktyk (ang. best practices) – sprawdzonych w praktyce zasad związanych z tworzeniem oprogramowania. Zasady te, zastosowane w połączeniu, uderzają w podstawowe przyczyny problemów i niepowodzeń procesu. Nazwa „najlepsze praktyki” wynika nie z faktu, że możemy zmierzyć ich poziom „dobroci”. Wynika raczej ze stwierdzenia, że są one najpowszechniej używane w organizacjach, które odnoszą sukcesy w produkcji oprogramowania. Najlepsze praktyki zostały zaczerpnięte od tysięcy takich organizacji i były stosowane w tysiącach projektów. Oto one:

·        Produkuj iteracyjnie, czyli oddawaj system w sposób przyrostowy.

·        Stosuj architektury komponentowe, czyli panuj nad złożonością systemu, miej spójną koncepcję całości i określ ramy dla radosnej twórczości projektantów i programistów.

·        Stale kontroluj jakość, czyli sprawdzaj poprawność systemu od samego początku projektu.

·        Zarządzaj wymaganiami, czyli traktuj wymagania jak jednostki, które podlegają procedurom zarządzania.

·        Zarządzaj zmianami, czyli z góry załóż, że zmiany na pewno będą ciągle zgłaszane.

·        Modeluj wizualnie, czyli twórz diagramy opisujące różne aspekty systemu, gdyż dobry rysunek jest wart więcej niż tysiąc słów.

Powyższe praktyki koncentrują się przede wszystkim na procesie technicznym i odpowiednim ujęciu go w formalne ramy konkretnych działań w różnych dyscyplinach. Inne podejście do praktyki inżynierii oprogramowania zostało wyrażone w tzw. manifeście zwinnego (ang. agile) wytwarzania oprogramowania (agilemanifesto.org). Brzmi on następująco:

„Odkrywamy nowe metody programowania dzięki praktyce w programowaniu i wspieraniu w nim innych. W wyniku naszej pracy, zaczęliśmy bardziej cenić:

  • Ludzi i interakcje od procesów i narzędzi,
  • Działające oprogramowanie od szczegółowej dokumentacji,
  • Współpracę z klientem od negocjacji umów,
  • Reagowanie na zmiany od realizacji założonego planu.

Oznacza to, że elementy wypisane po prawej są wartościowe, ale większą wartość mają dla nas te, które wypisano po lewej.”

Manifest – sformułowany przez grupę znanych praktyków wytwarzania oprogramowania – koncentruje się na aspekcie organizacyjnym i konieczności „zwinnego” (stąd nazwa) dostosowywania się do zmieniających się w projekcie warunków. Należy jednak podkreślić, że podejście zwinne nie neguje stosowania odpowiednich czynności technicznych (proces, narzędzia, dokumentacja). Uważa ono jednak, że zdecydowanie ważniejsze są czynniki poprawiające współpracę w zespole i reakcję na zmiany. Bardzo istotnym elementem jest zapewnienie satysfakcji klienta poprzez umożliwienie mu wczesnego (w cyklach kilkutygodniowych) zapoznawania się z ciągle rozbudowywanym oprogramowaniem. Jednocześnie, w projektach zwinnych mile widziane są zmiany treści wymagań, tak, aby je dostosować do rzeczywistych potrzeb klienta. Takie zmiany najczęściej „wykuwają” się w codziennej współpracy zespołu deweloperskiego z przedstawicielami klienta. Główną miarą postępu w projektach zwinnych jest działające oprogramowanie, które jest stale weryfikowane przez klienta. Taka ciągła weryfikacja sprzyja również ciągłemu procesowi poprawy efektywności pracy zespołu.

Najlepsze praktyki znajdują odzwierciedlenie w metodykach wytwarzania oprogramowania. Metodyki mogą być mniej lub bardziej sformalizowane oraz mogą obejmować różny zakres obszarów (dyscyplin) inżynierii oprogramowania. Metodyki oparte na podejściu zwinnym, zazwyczaj koncentrują się na aspektach organizacji pracy w zespołach wytwarzających oprogramowanie oraz często dostarczają różnych technik w obszarze programowania czy testowania. Przykładami takich metodyk są Scrum i eXtreme Programming (XP). Metodyki zwinne najczęściej nie formalizują opisu produktów technicznych w projekcie. Metodyki sformalizowane proponują natomiast szczegółowe wytyczne dla różnych czynności w procesie wytwarzania oprogramowania. Przykładem takiej metodyki jest Rational Unified Proccess (RUP) oraz jej „lekki” wariant – Open Unified Process (OpenUP). Opis każdej metodyki możemy oprzeć na trzech zasadniczych elementach: notacji, technikach i procesie technicznym.

  1. Proces techniczny organizuje techniki wykorzystywane w procesie wytwórczym w spójny ciąg czynności prowadzący do celu, jakim jest zbudowanie systemu na czas, w budżecie i spełniającego rzeczywiste potrzeby jego odbiorców.
    • Proces techniczny pozwala zorganizować czynności cyklu życia oprogramowania.
  2. Notacja dostarcza jednolitego języka dla porozumiewania się członków zespołu.
    • Notacja pozwala na jednoznaczne dokumentowanie wszystkich decyzji podejmowanych w projekcie.
  3. Techniki przedstawiają sposoby działania, które pokonują zasadnicze przyczyny niepowodzeń.
    • Techniki zarządzania wymaganiami koncentrują się na formułowaniu celów projektu z punku widzenia odbiorców (klientów, użytkowników) oprogramowania.
    • Techniki projektowania oprogramowania pozwalają panować nad złożonością systemów oprogramowania poprzez budowę ich planów architektonicznych i szczegółowych modeli kodu.
    • Techniki programowania przedstawiają zasady formowania kodu oraz zarządzania kodem w ramach zespołów programistów.
    • Techniki kontroli jakości dotyczą weryfikacji zgodności powstającego systemu z wymaganiami, czyli ściśle wiążą się z technikami zarządzania wymaganiami.