Co to jest NFR?
Na blogu często poruszamy temat analizy wymagań oprogramowania. Nie bez powodu - jest to ciągle niedoceniany etap pracy nad aplikacją lub systemem IT, a szalenie ważny, gdyż pozwala uświadomić zarówno klientowi, jak i zespołowi wykonawczemu, z czym właściwie się mierzą. Wśród fizycznych rezultatów analizy jest zazwyczaj dokument zwany specyfikacją wymagań oprogramowania, który zawiera wiele rozdziałów, a wśród nich te dotyczące wymagań. I o ile wymagania funkcjonalne są rdzeniem systemów oraz tym, z czym jednoznacznie kojarzy się opisywanie oprogramowania, to wiele osób zapomina o tym (lub nie jest świadoma), że istnieje drugi typ wymagań, uzupełniający funkcjonalność oraz pozwalający jej właściwie zabłysnąć.
Jak można się domyśleć, chodzi o wymagania pozafunkcjonalne (czasami nazywane też niefunkcjonalnymi), na które potocznie mówi się NFR-y od angielskiego Non-Functional Requirements. W przeciwieństwie do tych funkcjonalnych, które odpowiadają na pytanie "co będzie robił system", te dotyczą tego, "jak będzie to robił system". Czyli w tym przypadku interesują nas nie operacje dostępne dla użytkownika, ale takie aspekty jak:
- bezpieczeństwo.
- wydajność.
- dostępność.
- odporność na błędy.
- estetyka.
- stopień opisania (czytelność dokumentacji).
A także wiele, wiele innych. Nie ma bowiem co ukrywać, że nawet najbardziej wypakowana funkcjami aplikacja może nie odnieść sukcesu, jeśli nie zadba się o aspekty jakościowe i nie chodzi tutaj wcale o weryfikację, czy zwracane wyniki są poprawne. Na tle konkurencji liczyć się będą też drobiazgi, które poprawiają korzystanie z oprogramowania i po prostu sprawiają, że użytkownikowi przyjemnie korzysta się z aplikacji.
NFR-y mają swoje odzwierciedlenie zazwyczaj w dwóch obszarach - projektowaniu architektury oprogramowania oraz makiet i prototypów. Nierzadko zupełnie zmieniają podejście nawet do fundamentalnych spraw jak wybór technologii czy sam pomysł na interfejs. Dlatego warto zadbać o ich zbieranie (czasami dzieje się to wręcz przy okazji omawiania funkcjonalności) oraz dopytywanie klienta, gdy coś nie jest jasne. Ale do tego jeszcze dojdziemy.
Jak wygląda wymaganie pozafunkcjonalne?
W przypadku wymagań funkcjonalnych sposobów jest kilka - forma opisowa, opowieści użytkownika czy przypadki użycia. W przypadku NFR-ów sprawa wygląda teoretycznie dużo prościej - jest to zwykle po prostu jedno lub kilka zdań opisowych. Oto przykład:
System wymusza na użytkownikach stosowanie haseł o długości min. 8 znaków i wykorzystujących co najmniej jedną wielką literę i jedną cyfrę.
Wygląda prosto, prawda? Oczywiście, diabeł tkwi w szczegółach. Sama treść jest najważniejsza, ale często nie wystarczy, aby porządnie opisać kryteria w specyfikacji. Wymaganie pozafunkcjonalne jest zazwyczaj dodatkowo opatrzone następującymi atrybutami:
- Identyfikator - większość pozycji w specyfikacji wymagań powinna mieć nadany identyfikator w celu jasności przekazu i jednoznacznego odnoszenia się do poszczególnych elementów. Wymagania pozafunkcjonalne nie są wyjątkiem i także tutaj nadaje się im nazwy kodowe. W naszym przypadku zazwyczaj jest to
NFRXXX
(gdzie pod "XXX" znajduje się kolejny numer porządkowy), aczkolwiek w przypadku dużej liczby wymagań warto zastanowić się nad bardziej rozbudowaną numeracją. - Kategoria - wymaganie dotyczy konkretnej dziedziny, czyli właśnie kategorii. Będziemy o nich jeszcze dzisiaj pisać.
- Priorytet - oczekiwania klienta dotyczące oprogramowania można podzielić na te krytyczne, bez których nie ma co myśleć o realizacji systemu, takie, które powinny zostać spełnione oraz takie, o których można powiedzieć, że dobrze by było, gdyby się pojawiły, ale jeśli tak się nie stanie, to trudno. Krótko mówiąc, NFR-y także ulegają priorytetyzacji, przy której zazwyczaj stosuje się poziomy H, M i L omawiane już przy analizie ryzyka.
- Trudność - nie da się ukryć, że nie wszystkie wymagania łatwo spełnić i klient również musi brać to pod uwagę, głównie w kontekście wyceny. Dlatego atrybut trudności (o poziomach podobnych jak priorytet) pozwala określić poziom skomplikowana danej pozycji lub nawet wskazać, że powinna ona zostać podzielona na mniejsze elementy.
- Opis weryfikacji - dobre wymaganie pozafunkcjonalne to takie, które można zweryfikować. Problem w tym, że nie zawsze wiadomo, jak to zrobić, dlatego czasami przybliża się tę metodę jednym zdaniem. Dotyczy to głównie bardzo formalnych projektów o wysokim poziomie dokumentowania szczegółów.
Oczywiście, nie jest to zamknięta lista, podobnie jak zazwyczaj tylko część atrybutów jest umieszczana w specyfikacji. Może się to wiązać z "typowością" projektu (gdy jest coś zrozumiałe, to nie trzeba tego aż tak rozpisywać), dostępnym budżetem, harmonogramem, a także oczekiwaniami klienta.
Kategorie wymagań pozafunkcjonalnych
Wcześniej wspomnieliśmy o kategoriach, czyli de facto obszarach pozafunkcjonalnych, w których można szukać aspektów jakościowych. Dla niektórych mogą być niepotrzebnie komplikującym sprawę ozdobnikiem, ale bardziej doświadczeni analitycy z łatwością wskażą ich zalety. Są to między innymi:
- porządkowanie zbierania wymagań i zminimalizowanie ryzyka zapomnienia o jakimś obszarze,
- wspomaganie procesu analitycznego poprzez doszukiwanie się aspektów, o których teoretycznie nie myśli się w pierwszej chwili (taka checklista),
- podzielenie wymagań na sekcje, co skutkuje np. lepszym planowaniem spotkań,
- ograniczenie niejednoznaczności dotyczącej tego, czego właściwie dotyczy dane wymaganie.
Często proponuje się hierarchię kategorii ustanowioną przez standard ISO 25010, który jest szeroko wykorzystywany w branży przy definiowaniu oraz badaniu jakości oprogramowania. Jest też omawiany na uczelniach, np. Politechnice Poznańskiej dzięki p. dr inż. Sylwii Kopczyńskiej, niestrudzonej badaczce zagadnienia wymagań pozafunkcjonalnych. Obecność tego standardu w środowisku akademickim sprawiło, że wzrosło jego upowszechnienie.
Nie przedłużając, mamy tutaj nawet trzy poziomy kategoryzacji, przy czym pierwszy z nich pomaga bardziej w ustaleniu, które tematy warto poruszyć z daną osobą, a z kolejnych dwóch często wybiera się pierwszy. Tym niemniej, warto znać całą hierarchię, gdyż pozwala to poszerzyć horyzonty przy analizy systemu jeszcze przed jego powstaniem. Poniżej podział, który został szerzej opisany w przytoczonym dokumencie.
- Jakość produktu
- Funkcjonalne dopasowanie
- Funkcjonalna kompletność
- Funkcjonalna poprawność
- Funkcjonalna odpowiedniość
- Wydajność
- Charakterystyka czasowa
- Zużycie zasobów
- Oczekiwana wydajność
- Kompatybilność
- Współistnienie
- Interoperacyjność
- Użyteczność
- Rozpoznawalność zastosowania
- Łatwość nauczenia się
- Łatwość operowania
- Ochrona użytkownika przed błędami
- Estetyka interfejsu użytkownika
- Dostępność personalna
- Niezawodność
- Dojrzałość
- Dostępność techniczna
- Odporność na wady
- Odtwarzalność
- Bezpieczeństwo
- Poufność
- Integralność
- Niezaprzeczalność
- Identyfikowalość
- Autentyczność
- Łatwość utrzymania
- Modułowość
- Łatwość ponownego użycia
- Łatwość analizy
- Łatwość modyfikowania
- Łatwość testowania
- Przenośność
- Łatwość adaptacji
- Łatwość instalacji
- Łatwość zamiany
- Jakość użycia
- Efektywność
- Sprawność
- Satysfakcja
- Wolność od ryzyka
- Pokrycie kontekstu
- Kompletność kontekstowa
- Elastyczność
Jak widać, te punkty docierają do praktycznie każdego aspektu, który można rozważać na poziomie oprogramowania. Mamy tutaj m.in. bezpieczeństwo (w znaczeniu security oraz safety, a więc obejmujące zarówno intencjonalne działania, jak i przypadkowe zdarzenia), estetykę, kwestie wdrożeniowe, wydajnościowe, a także ochronę przed błędami. Naturalnie, nie ma obowiązku poruszania każdego aspektu z klientem lub nawet stosowania się do tego standardu, natomiast warto chociaż przejrzeć tę listę i przemyśleć, czy istotnie w naszym oprogramowaniu nie występują przytoczone sytuacje, w których zachowanie systemu należy rozważyć.
SMART - cechy określające dobre wymaganie
Podawaliśmy wcześniej, jak opisywać wymaganie pozafunkcjonalne. Jednak trzymanie się tego planu wcale nie oznacza, że wyspecyfikowane NFR-y będą dobre. Co zatem pozwoli nam to sprawić i co właściwie oznacza, że wymaganie jest "dobre"?
Istnieje technika SMART (pisana też jako S.M.A.R.T.), która pomaga w definiowaniu celów np. przy zarządzaniu projektami. Została zaproponowana w 1981 r. przez George'a T. Dorana, Arthura Millera oraz Jamesa Cunninghama i z uwagi na to, że NFR-y de facto są pewnymi celami do spełnienia, to sprawdzą się też w przypadku omawianego tematu. Warto również wspomnieć, że czasem ten skrót wzbogacany jest o dodatkowe cechy ER (tworząc SMARTER), aczkolwiek nie jest to w kanonie i należy traktować jako ciekawostkę oraz możliwe rozszerzenia.
No dobrze, ale czym jest ten SMART i jak nam może pomóc? Pisał już o tym Piotr Miklosik w artykule o specyfikacji wymagań, a także wielu autorów w innych miejscach w sieci, natomiast dla porządku należy tutaj rozwinąć ten fragment. Aby wymaganie pozafunkcjonalne rzeczywiście przyczyniło się do polepszenia jakości oprogramowania i - co ważniejsze - zadowolenia klienta oraz użytkowników, powinniśmy podążać za następującymi wskazówkami.
Wymaganie powinno być proste w zrozumieniu i konkretne (Simple and Specific). Nikomu nie zależy na tym, aby opis był niejednoznaczny i można go było interpretować na różne sposoby lub po prostu był niezrozumiały. Tutaj trzeba podejść do tego ściśle i precyzyjnie opisać, o co chodzi.
Przykład dobrego wymagania: Hasła do logowania użytkownikom daje użytkownik o roli administratora.
Przykład złego wymagania: Użytkownicy mogą używać haseł przesłanych przez administratorów. (do czego hasła, jeśli mogą to czy muszą, kim jest administrator...)
Prawdopodobnie najważniejszą literką jest tutaj "M", gdyż oznacza, że wymaganie musi być mierzalne (Measurable). Wyobraźmy sobie sytuację, w której następuje różnica zdań pomiędzy stronami w projekcie o to, czy dany NFR został spełniony. Jeśli nie ma jasnych kryteriów weryfikacji, to sytuacja jest niejednoznaczna, gdyż każda strona będzie negocjowała z korzyścią w jedną stronę, a taka sytuacja nie jest na rękę nikomu. W dodatku programiści muszą mieć jasną informację, do jakiego celu mają dążyć.
Przykład dobrego wymagania: Raport zamówionych materiałów jest generowany w czasie co najwyżej 10 sekund.
Przykład złego wymagania: Raport zamówionych materiałów jest generowany szybko. (co to znaczy "szybko")
Pamiętacie, gdy wspominałem o trudności? Wiadomo, że oczekiwania wobec oprogramowania mogą być duże, jednak należy zadbać o to, aby były osiągalne (Achievable lub Attainable). Najczęściej dotyczy to kwestii wydajnościowych lub zasobowych, aczkolwiek nie można także brać pod uwagę wymagań, które są poza zasięgiem kompetencji osób biorących udział w projekcie przy jednoczesnym braku środków na np. outsourcing.
Przykład dobrego wymagania: Aplikacje webowa musi umożliwiać korzystanie ze wszystkich funkcji przy połączeniu internetowym o przepustowości 10 MB/s.
Przykład złego wymagania: Aplikacje webowa musi umożliwiać korzystanie ze wszystkich funkcji bez aktywnego połączenia internetowego. (wbrew pozorom, to może mieć sens, ale zazwyczaj nie jest możliwe do spełnienia, chyba że z zastosowaniem takich technik jak PWA, buforowanie danych lub działanie w sieciach wewnętrznych)
Może również zaistnieć sytuacja, w której klient podaje bardzo dużo ograniczeń dla projektu, jednak po analizie okazuje się, że nie wszystkie mają sens w danym przypadku. Ten temat został już nieco zaczęty przy literce "A", jednak należy pamiętać, że wymaganie musi mieć znaczenie (Relevant). Jeśli go nie ma, to nie jest uzasadnione wprowadzanie go do specyfikacji, gdyż tylko zaciemni obraz i niepotrzebnie będzie kłopotał wszystkich odbiorców dokumentacji. Trudno tutaj podać przykład - można np. przyjąć, że nadanie obowiązku wprowadzenia wielojęzyczności nie ma sensu przy aplikacjach przeznaczonych tylko dla jednej firmy komunikującej się w języku polskim, natomiast nie jest wykluczone, iż w przyszłości nie będą potrzebne różne wersje językowe przy rozszerzaniu kręgu odbiorców systemu. Znacznie bardziej trafne byłoby przytoczenie wymagania "System przechowuje kwoty pieniężne z dokładnością do dwóch miejsc po przecinku" dla systemu, w którym w ogóle nie będą przetwarzane wartości finansowe.
I wreszcie - wymaganie powinno być odpowiednio umieszczone w czasie (Timed), natomiast warto wspomnieć o tym, że specyfikacja wymagań (w tym też rejestr wymagań pozafunkcjonalnych) nie jest równoznaczna harmonogramowi. Owszem, może zawierać informacje o rzeczach priorytetowych dla klienta, jednak należy pamiętać o tym, że zapewnianie spełnienia wymagań pozafunkcjonalnych jest procesem ciągłym i musi być stale utrzymywane wraz z powstającą funkcjonalnością. Przykładowo, co z tego, że dla listy użytkowników zostanie zapewnione zapamiętywanie filtrów, skoro w następnych sprintach pojawią się jeszcze listy klientów oraz zamówień, przy których też należy pamiętać o tym wymaganiu. Jednak może istnieć sytuacja, w której dany NFR musi (i może) zostać spełniony do konkretnego momentu - w takim układzie warto umieścić odpowiednią adnotację.
SMART nie jest jedyną metodą pomagającą w tworzeniu celów czy wymagań pozafunkcjonalnych. Istnieją jeszcze inne, które warto znać, jednak omówiona technika z lat 80. nadal jest powszechnie wykorzystywana.
Technika zbierania wymagań pozafunkcjonalnych
Klasycznie proces pozyskiwania NFR-ów, który jest przedstawiany podczas zajęć z inżynierii oprogramowania czy zarządzania projektami, przebiega mniej więcej w taki sposób:
- Umawiane są spotkania z różnymi interesariuszami: klientem, osobami technicznymi i użytkownikami (powinny być to osobne, niezależne spotkania).
- Przygotowywana jest osobna lista kategorii i podkategorii dla każdego spotkania (nie każda grupa zainteresowana jest wszystkimi aspektami systemu).
- Na spotkaniach prezentowane są po kolei kategorie i dyskutowane oczekiwania klienta w danym obszarze (w myśl zasady, że każdy pomysł jest dobry).
- Po zakończeniu prezentacji omawiane są pozyskane punkty i ustalane priorytety.
- Po wszystkich spotkaniach prezentowany jest rejestr NFR-ów do akceptacji.
Natomiast nie ukrywajmy - w normalnych warunkach i dla małych oraz średnich projektów ten sposób działania nie jest możliwy do przeprowadzenia w praktyce. Wymaga dużej ilości czasu, zgrania terminów, a klientowi zazwyczaj zależy na czasie. Owszem, to bardzo dobry sposób działania, ale w większości projektów (pomijając te o krytycznym znaczeniu bądź mające ogromny budżet) należy podejść do tego zdroworozsądkowo i stosować się do kilku zasad.
Po pierwsze, zleceniodawcy, omawiając swoje oczekiwania związane z systemem, zazwyczaj skupiają się na funkcjonalności. Jednak bardzo często przy okazji jej definiowania poruszają także tematy jakościowe, wskazując rzeczy, na które będą zwracać uwagę lub które podpatrzyli w innych aplikacjach. Tego typu momenty to podstawowe źródło wymagań pozafunkcjonalnych, nawet jeśli nie jesteśmy świadomi ich w rozmowie na żywo. Dlatego bardzo istotne jest wyrobienie sobie nawyku sporządzania dobrych notatek, których późniejsza analiza rozwija nam rejestr NFR-ów (między innymi).
Po drugie, im więcej projektów analizujemy i specyfikujemy, tym mamy większe doświadczenie i dane historyczne. A z uwagi na to, że wiele systemów konstrukcyjnie jest do siebie podobnych (mimo że funkcjonalnie zupełnie się różnią), to zakres NFR-ów też może być podobny. To z kolei oznacza, że warto tworzyć sobie takie wewnętrzne katalogi najczęstszych wymagań pozafunkcjonalnych i korzystać z tej listy przy pisaniu specyfikacji dla nowego systemu. Nawet, jeśli poszczególne pozycje nie zostaną wykorzystane, to mogą uruchomić w mózgu procesy myślowe, które pozwolą rozpatrzyć podobne aspekty. Istnieją też formalnie opisane metody bazujące na szablonach, jak choćby NoRT autorstwa wspomnianej już dr inż. Sylwii Kopczyńskiej, natomiast w warunkach uwzględniających określony budżet tworzenie wewnętrznych katalogów również powinno dać dobre rezultaty przy jednoczesnej oszczędności czasu.
Po trzecie, warto posługiwać się wcześniej przytoczonymi kategoriami i samemu przejść je podczas analizy wymagań. Istnieje duża szansa, ża w ten sposób sami wypiszemy pozycje ważne dla projektu (bazując na wiedzy zdobytej, nawet nieświadomie, podczas spotkań z klientem), a inne oznaczymy jako prawdopodobne w celu dopytania zleceniodawcy. W ten sposób możemy wykonać część pracy i umówić się na weryfikację mając już konkretny materiał, co nie tylko stawia nas w dobrym świetle, ale też pozwoli mniejszym kosztem zdobyć najważniejsze informacje.
Oczywiście, za każdym razem rejestr NFR-ów, podobnie jak inne elementy specyfikacji wymagań, muszą być zaakceptowane przez klienta i uzupełnione o ewentualnie wskazane braki.
Podsumowanie
Czy warto identyfikować i spisywać wymagania pozafunkcjonalne? Oczywiście, że warto - to one nadają ograniczenia ważne z punktu widzenia architektury i pozwalające nam lepiej dobrać narzędzia, którymi będziemy posługiwać się przy realizacji. Mają też duże przełożenie na wycenę, dodając kolejne punkty do kosztorysu bądź modyfikując oszacowanie godzinowe innych wymagań. Jednocześnie, ich dobre wyspecyfikowanie i późniejsza realizacja istotnie pozwalają podnieść jakość tworzonego systemu, dzięki czemu będzie on miał większą szansę zaistnieć i spodobać się użytkownikom. A na tym zależy wszystkim osobom pracującym nad projektem.
Pozdrawiam i dziękuję - Jakub Rojek.