Co powinniśmy zapamiętać
Wymagania w inżynierii oprogramowania
Wymagania odpowiadają na najistotniejsze w całym procesie budowy oprogramowania pytanie, „jaki system mamy zbudować?” W dobrze zorganizowanym procesie wytwórczym, wymagania sterują konstrukcją systemu. Jakość wymagań jest kluczowym elementem powodzenie każdego projektu konstrukcji systemu oprogramowania. Wymagania powinny być kompletne, jednoznaczne, poprawne, spójne (niesprzeczne), możliwe do zarządzania oraz testowalne. Aby sformułować dobrej jakości wymagania musimy uzyskać dostęp do odpowiednich źródeł informacji. Można tutaj wyróżnić źródła osobowe (ludzi) oraz źródła nieosobowe (np. dokumenty). Pisząc wymagania należy pamiętać o tym, że będą z nich korzystały bardzo różnorodne grupy osób. Możemy tu wyróżnić osoby po stronie zamawiającego (np. firma zamawiająca), jak i po stronie wykonawcy (np. firma wykonująca system).
Specyfikowanie środowiska (biznesu)
Wdrożenie w przedsiębiorstwie nowego lub rozbudowanie dotychczasowego systemu oprogramowania często powoduje istotne zmiany w sposobie jego organizacji oraz sposobie realizacji procesów biznesowych. Dlatego też, zanim rozpoczniemy etap analizy i formułowania wymagań dla systemu, musimy poznać elementy środowiska biznesowego przedsiębiorstwa, dla którego ten system ma być zbudowany. W szczególności, powinniśmy dobrze zrozumieć procesy w nim zachodzące, a w tym – jego strukturę organizacyjną, produkty pracy i systemy informatyczne. Procesy biznesowe modelujemy np. w językach BPMN lub UML. Proces biznesowy w języku UML możemy zamodelować jako przypadek użycia biznesu opisany modelem czynności.
Struktura specyfikacji wymagań
Dla powodzenia projektu konstrukcji oprogramowania kluczowe jest przedstawienie zgromadzonych wymagań w systematyczny sposób, zapewniający spełnienie kryteriów jakościowych. Dobrze zbudowana specyfikacja wymagań ma strukturę piramidy z trzema poziomami – wizją systemu, wymaganiami użytkownika oraz wymaganiami oprogramowania. Wyróżniamy cztery podstawowe typy wymagań (kolumny piramidy) – wymagania funkcjonalne, wymagania jakościowe, wymagania słownikowe oraz ograniczenia. Specyfikacje wymagań mogą być sformułowane na różnym poziomie formalności. Często wymagane jest utworzenie formalnego dokumentu – specyfikacji wymagań zamawiającego, który będzie składnikiem umowy między zamawiającym a wykonawcą. Struktura takiego dokumentu zależy od przyjętych konwencji, ale powinna obejmować wszystkie typy wymagań. Na poziomie specyfikacji wymagań oprogramowania, wymagania zamawiającego są dodatkowo uszczegóławiane.
Wizja systemu
Wizja systemu oprogramowania jest opisem potrzeb zamawiającego, dotyczącego systemu oprogramowania, przedstawiona na stosunkowo wysokim poziomie ogólności. Specyfikacja na poziomie wizji zbiera w jedną całość opis najważniejszych problemów biznesu oraz wynikających z nich cech produktu software’owego. Wizja systemu powinna dawać odpowiedź na podstawowe pytania: „Po co budujemy nowy system?”, „Jakie problemy naszego biznesu ten system rozwiąże?”, „Dla kogo jest ten system?”, „Jakie cechy ma mieć ten system, aby pokonać zidentyfikowane problemy?”. Na wizję systemu mogą się składać takie elementy jak stwierdzenie problemu, specyfikacja interesariuszy, lista cech systemu oraz słownik pojęć danej dziedziny.
Wymagania użytkownika
Wymagania użytkownika specyfikują wymagania na system w sposób wystarczający do określenia jego rozmiaru i nakładu pracy potrzebnej do jego zbudowania. Specyfikacja wymagań użytkownika powinna dostarczyć odpowiedzi na kluczowe w procesie zarządzania projektem pytania: „Jak obszerna będzie funkcjonalność systemu?”, „Jakie dane będzie przetwarzał system?”, „Kto będzie się posługiwał systemem?”, „Ile system będzie kosztował?”. Proces powstawania specyfikacji wymagań użytkownika możemy nazwać procesem „łowienia wymagań”, które polega na aktywnym odkrywaniu szczegółowych potrzeb zamawiającego przy wykorzystaniu różnych technik. Wymagania funkcjonalne na poziomie wymagań użytkownika formułuje się najczęściej przy wykorzystaniu modelu przypadków użycia lub w formie historii użytkownika. Formułując wymagania jakościowe należy posługiwać się odpowiednimi normami, aby nie pominąć istotnych obszarów jakościowych systemu. Bardzo istotne jest sformułowanie metryk pozwalających zweryfikować spełnienie wymagań jakościowych. Słownik dziedziny korzystnie jest przedstawić w formie graficznej jako model klas.
Wymagania oprogramowania
Wymagania oprogramowania stanowią uszczegółowienie wymagań użytkownika. Na tym poziomie piramidy wymagań, przypadki użycia (ew. historie użytkownika) zdefiniowane podczas formułowania wymagań użytkownika są opisywane w szczegółach, poprzez zdefiniowanie ich scenariuszy. Korzystne jest stosowanie jednolitej notacji dla scenariuszy (np. notacji POD), w tym np. wykorzystanie notacji graficznej (diagramy czynności). W miarę tworzenia scenariuszy uszczegóławiany i uzupełniany jest słownik dziedziny oraz ustalany jest wygląd interfejsu użytkownika, a także tworzone scenopisy. Kompletna specyfikacja wymagań oprogramowania zawiera również rozbudowaną specyfikację wymagań jakościowych, gdzie nowe lub zaktualizowane wymagania wynikają z uszczegółowienia wymagań funkcjonalnych i słownika. Źródłem dla wymagań oprogramowania jest definicja zakresu systemu w postaci modelu przypadków użycia oraz powiązany z nimi słownik (model) dziedziny.
Rola architektury oprogramowania
Podstawowym składnikiem dobrych praktyk inżynierii oprogramowania jest stworzenie projektu architektonicznego pokazującego zasadniczą strukturę systemu oraz opisującego sposób działania podstawowych jednostek funkcjonalnych. Plany architektoniczne systemu powinny zapewniać członkom zespołu deweloperskiego dobrą platformę porozumienia – powinny wyrażać najważniejsze decyzje dotyczące sposobu budowy systemu. Architekturę oprogramowania tworzymy na stosunkowo wysokim poziomie ogólności. Architekt tworzy ogólny model systemu, dzieląc jego funkcjonalność na poszczególne komponenty oraz definiując interfejsy i przepływ komunikatów pomiędzy komponentami.
Architektury komponentowe i usługowe
Kluczową decyzją architektoniczną jest podział systemu na komponenty. Dobra architektura definiuje podział systemu na komponenty o wysokiej zwartości posiadających jednocześnie słabe więzy z innymi komponentami. Komponenty komunikują się ze sobą tylko w pewnych kluczowych momentach działania poszczególnych przypadków użycia systemu. Wewnątrz komponentów zawarta jest cała logika przetwarzania danych, a także logika interakcji z użytkownikami i systemami zewnętrznymi. Logika zawarta w danym komponencie jest ukryta dla komponentów pozostałych. Komponenty nawzajem oczekują od siebie jedynie efektów swojej pracy i co więcej – nie mogą od siebie wymagać nic więcej ponad te efekty. Dobrze zdefiniowane i reużywalne komponenty nazywamy usługami. Usługi mogą być dostępne w sieci i wtedy takie usługi nazywamy usługami webowymi.
Style architektoniczne
Dobrze zaprojektowana architektura oprogramowania przestrzega określonego stylu architektonicznego, który definiuje sposób podziału komponentów. Najpowszechniej stosowanym podziałem komponentów jest architektura warstwowa. Najprostszym stylem architektonicznym jest podział na dwie warstwy, czasami nazywany architekturą klient-serwer. Warstwa górna stanowi witrynę (frontend) i odpowiada za interakcję z użytkownikiem, a warstwa dolna stanowi zaplecze (backend) i odpowiada za przetwarzanie i przechowywanie danych. Często stosuje się także architekturę wielowarstwową, przy czym najczęściej wyróżnia się cztery zasadnicze warstwy: widok, logikę aplikacji, logikę dziedzinową i przechowywanie danych. Komponenty poszczególnych warstw należy zainstalować na odpowiednich jednostkach wykonawczych, co jest projektowane w ramach architektury fizycznej. W złożonych systemach projektuje się architekturę fizyczną rozproszoną, która zakłada istnienie kilku różnych typów węzłów wykonawczych usługowych (serwerów).
Architektura na podstawie wymagań
Projekt architektoniczny powinien przede wszystkim umożliwiać realizację wymagań, jednocześnie uwzględniając kwestie techniczne. Warto jest korzystać z reguł przekształcania wymagań w projekt architektoniczny. Reguły takie obejmują m.in. projektowanie komponentów na podstawie pakietów wymagań, tworzenie interfejsów na podstawie jednostek wymagań funkcjonalnych oraz pojęć słownikowych, a także definiowane operacji interfejsów na podstawie scenariuszy. Można również stosować reguły projektowania obiektów transferu danych na podstawie słownika dziedziny, a także – sekwencji komunikatów wykorzystujących te obiekty.
Projektowanie frontendu
Komponenty warstw prezentacji i logiki aplikacji tworzą zazwyczaj spójną całość, nazywaną frontendem. Głównym zadaniem podczas projektowania frontendu jest zaprojektowanie elementów odpowiedzialnych za obsługę interfejsu użytkownika oraz logikę nawigacji między tymi elementami. Bardzo istotne jest również zaprojektowanie współpracy z warstwą logiki dziedzinowej. Projektując frontend powinniśmy wyraźnie wydzielić te elementy, które są silnie zależne od technologii interfejsu użytkownika oraz technologii wymiany danych. Bardzo wskazane jest dokonanie podziału na kod „brudny” i kod „czysty”. Klasy „brudne” są najczęściej zależne od konkretnego szkieletu technologicznego (ang. framework).
Projektowanie logiki dziedzinowej
Logika dziedzinowa może być umieszczona w tym samym węźle wykonawczym i być ściśle powiązana z elementami logiki aplikacji lub być dostępna zdalnie jako np. usługa webowa. Zasadnicza funkcjonalność logiki dziedzinowej zazwyczaj projektowana jest jako zestaw niezależnych komponentów, często traktowanych jako usługi. Dla każdego takiego komponentu projektowany jest jeden lub więcej interfejsów (fasad), zawierających odpowiednie zestawy operacji na obiektach dotyczących danej dziedziny problemu. Projekt kodu logiki dziedzinowej może być oparty na określonych wzorcach, np. jako skrypt transakcyjny lub model dziedziny.
Projektowanie bazy danych
Komponenty warstwy przechowywania danych mogą być realizowane w różnych technologiach i mogą przechowywać dane różnego rodzaju w różnych formatach i strukturach. Najczęściej używanymi paradygmatami przechowywania danych są bazy danych relacyjne oraz bazy danych nierelacyjne. Projektowanie baz relacyjnych polega przede wszystkim na opracowaniu struktury bazy danych składającej się z tabel, kolumn, wierszy i powiązań. Podstawą takiego projektu może być model dziedzinowy, który należy przekształcić do modelu relacyjnego. Bazy danych nierelacyjne najczęściej są oparte na strukturach danych zgodnych z paradygmatem obiektowym, zatem nie wymagają przekształcania modelu dziedzinowego wyrażonego np. jako model klas.