Dane oryginału

Authorized translation from the English language edition, entitled SOFTWARE ENGINEERING, 10tf Edition by SOMMERVILLE, IAN, published by Pearson Education, Inc, publishing as Pearson, Copyright © 2016 Pearson Higher Education, Inc.

All rights reserved. No part of this book may be reproduced or transmited in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from Pearson Education, Inc. POLISH language edition published by POLISH SCIENTIFIC PUBLISHERS PWN, Copyright 2020.

Autoryzowane tłumaczenie wydania w języku angielskim zatytułowane SOFTWARE ENGINEERING, Wydanie 10 autorstwa IAN SOMMERVILLE opublikowane przez Pearson Education, Inc, publikującym jako Pearson, Copyright © 2016 Pearson Higher Education, Inc.

Wszelkie prawa zastrzeżone. Żadna część tej książki nie może być powielana ani przesyłana w żadnej formie ani w jakikolwiek sposób, elektroniczny lub mechaniczny, w tym przez kopiowanie, nagrywanie lub przez dowolny system wyszukiwania informacji, bez zgody Pearson Education, Inc. POLSKIE wydanie językowe opublikowane przez WYDAWNICTWO NAUKOWE PWN. Spółka akcyjna, Copyright 2020.

Przekład Marek Włodarz na zlecenie WITKOM Witold Sikorski

Projekt okładki polskiego wydania INT-MEDIA Dawid Mazur na podstawie oryginału

Wydawca Wioleta Szczygielska-Dybciak

Redaktor prowadzący Jolanta Kowalczuk

Redaktor Irena Puchalska

Koordynator produkcji Anna Bączkowska

Konsultacja merytoryczna

prof. dr hab. Krzysztof Stencel

Zastrzeżonych nazw firm i produktów użyto w książce wyłącznie w celu identyfikacji.

Skład wersji elektronicznej na zlecenie Wydawnictwa Naukowego PWN

Monika Lipiec /Woblink

Copyright © for the Polish edition by Wydawnictwo Naukowe PWN SA

Warszawa 2020

ISBN 978-83-01-21455-5

eBook został przygotowany na podstawie wydania papierowego z 2020 r., (wyd.X (I w WN PWN))

Warszawa 2020

Wydawnictwo Naukowe PWN SA

02-460 Warszawa, ul. Gottlieba Daimlera 2

tel. 22 69 54 321, faks 22 69 54 288

infolinia 801 33 33 88

e-mail: pwn@pwn.com.pl; reklama@pwn.pl

www.pwn.pl

Spis treści

1. Przedmowa

Część 1. Wprowadzenie do inżynierii oprogramowania

1. Wprowadzenie

1.1 Profesjonalne wytwarzanie oprogramowania

1.2 Etyka inżynierii oprogramowania

1.3 Studia przypadków

2. Procesy wytwarzania oprogramowania

2.1 Modele procesu wytwarzania oprogramowania

2.2 Czynności procesowe

2.3 Radzenie sobie ze zmianami

2.4 Ulepszanie procesu wytwarzania

3. Zwinne wytwarzanie oprogramowania

3.1 Metodyki zwinne

3.2 Zwinne techniki wytwarzania

3.3 Zwinne zarządzanie projektem

3.4 Skalowanie metodyk zwinnych

4. Inżynieria wymagań

4.1 Wymagania funkcjonalne i pozafunkcjonalne

4.2 Procesy inżynierii wymagań

4.3 Ujawnianie wymagań

4.4 Specyfikowanie wymagań

4.5 Walidacja wymagań

4.6 Zmiany wymagań

5. Modelowanie systemu

5.1 Modele kontekstowe

5.2 Modele interakcji

5.3 Modele strukturalne

5.4 Modele behawioralne

5.5 Architektura sterowana modelami

6. Projekt architektoniczny

6.1 Decyzje dotyczące projektu architektonicznego

6.2 Widoki architektoniczne

6.3 Wzorce architektoniczne

6.4 Architektury aplikacji

7. Modelowanie systemu

7.1 Projektowanie obiektowe z wykorzystaniem UML

7.2 Wzorce projektowe

7.3 Problemy implementacyjne

7.4 Wytwarzanie oprogramowania open source

8. Testowanie oprogramowania

8.1 Testy wytwórcy

8.2 Wytwarzanie sterowane testami

8.3 Testy wydania

8.4 Testy użytkownika

9. Ewolucja oprogramowania

9.1 Procesy ewolucji

9.2 Systemy odziedziczone

9.3 Konserwacja oprogramowania

Część 2. Rzetelność i zabezpieczenia

10. Rzetelne systemy

10.1 Cechy rzetelności

10.2 Systemy socjotechniczne

10.3 Nadmiarowość i różnorodność

10.4 Rzetelne procesy

10.5 Metody formalne a rzetelność

11. Inżynieria niezawodności

11.1 Dostępność i niezawodność

11.2 Wymagania niezawodności

11.3 Architektury tolerujące awarie

11.4 Programowanie pod kątem niezawodności

11.5 Mierzenie niezawodności

12. Inżynieria bezpieczeństwa

12.1 Systemy krytyczne ze względów bezpieczeństwa

12.2 Wymagania bezpieczeństwa

12.3 Procesy inżynierii bezpieczeństwa

12.4 Analizy bezpieczeństwa

13. Inżynieria zabezpieczeń

13.1 Zabezpieczenia i rzetelność

13.2 Zabezpieczenia i firmy

13.3 Wymagania zabezpieczeń

13.4 Projektowanie zabezpieczonych systemów

13.5 Testowanie i gwarantowanie zabezpieczeń

14. Inżynieria odporności

14.1 Bezpieczeństwo cybernetyczne

14.2 Odporność socjotechniczna

14.3 Projektowanie systemów odpornych

Część 3. Zaawansowana inżynieria oprogramowania

15. Ponowne użycie oprogramowania

15.1 Ogólny przegląd ponownego użycia

15.2 Platformy aplikacji

15.3 Linie oprogramowania na sprzedaż

15.4 Ponowne użycie systemów użytkowych

16. Komponentowa inżynieria oprogramowania

16.1 Komponenty i modele komponentowe

16.2 Procesy CBSE

16.3 Składanie komponentów

17. Inżynieria oprogramowania rozproszonego

17.1 Systemy rozproszone

17.2 Przetwarzanie klient-serwer

17.3 Wzorce architektoniczne systemów rozproszonych

17.4 Oprogramowanie jako usługa

18. Usługocentryczna inżynieria oprogramowania

18.1 Architektury usługocentryczne

18.2 Usługi RESTful

18.3 Inżynieria usług

18.4 Komponowanie usług

19. Inżynieria systemów

19.1 Systemy socjotechniczne

19.2 Projekt koncepcyjny

19.3 Zamawianie systemu

19.4 Wytwarzanie systemu

19.5 Działanie i ewolucja systemu

20. Systemy systemów

20.1 Złożoność systemu

20.2 Klasyfikowanie systemów systemów

20.3 Redukcjonizm i systemy złożone

20.4 Inżynieria systemów systemów

20.5 Architektury systemów systemów

21. Inżynieria oprogramowania czasu rzeczywistego

21.1 Projektowanie systemów wbudowanych

21.2 Wzorce architektoniczne oprogramowania czasu rzeczywistego

21.3 Analiza synchronizacji

21.4 Systemy operacyjne czasu rzeczywistego

Część 4. Zarządzanie oprogramowaniem

22. Zarządzanie projektem

22.1 Zarządzanie ryzykiem

22.2 Zarządzanie ludźmi

22.3 Praca zespołowa

23. Planowanie projektu

23.1 Wycenianie oprogramowania

23.2 Wytwarzanie planowe

23.3 Tworzenie harmonogramu projektu

23.4 Planowanie zwinne

23.5 Techniki szacowania

23.6 Metodyka modelowania kosztów COCOMO

24. Zarządzanie jakością

24.1 Jakość oprogramowania

24.2 Standardy oprogramowania

24.3 Przeglądy i inspekcje

24.4 Zarządzanie jakością a wytwarzanie zwinne

25. Zarządzanie konfiguracją

25.1 Zarządzanie wersjami

25.2 Budowanie systemu

25.3 Zarządzanie zmianami

25.4 Zarządzanie wydaniami

25.5 Miernictwo oprogramowania

Słownik

Przypisy

Część 1.
Wprowadzenie do inżynierii oprogramowania

Ta część książki ma na celu przedstawienie ogólnego wprowadzenia do inżynierii oprogramowania. Rozdziały w niej zamieszczone są pomyślane jako materiał wspomagający początkowego wykładu na jeden semestr. Wprowadzam w niej ważne koncepcje, takie jak procesy wytwarzania oprogramowania, metodyki zwinne, i opisuję podstawowe czynności związane z produkcją oprogramowania – od specyfikowania wymagań po ewolucję systemu.

Rozdział 1 jest ogólnym wprowadzeniem przedstawiającym pojęcie profesjonalnej inżynierii oprogramowania i definiującym niektóre pojęcia z tej dziedziny. Dołączyłem tu również krótkie omówienie zagadnień etycznych związanych z inżynierią oprogramowania. Ważne jest, aby inżynierowie oprogramowania mieli świadomość szerszych implikacji wykonywanej przez nich pracy. Rozdział ten zawiera również wprowadzenie do czterech studiów przypadków, których używam w całej książce. Są to system informacyjny zarządzający rejestrami pacjentów przechodzących leczenie chorób psychicznych (Mentcare), system sterujący przenośną pompą insulinową, wbudowany system automatycznej stacji pogodowej oraz cyfrowe środowisko nauczania (iLearn).

Rozdziały 2 i 3 zawierają omówienie procesów wytwarzania oprogramowania i projektowania zwinnego. W rozdziale 2 przedstawiam modele procesów wytwarzania oprogramowania, takie jak model kaskadowy, a także omawiam podstawowe czynności składające się na te procesy. Rozdział 3 uzupełnia tę tematykę omówieniem metodyk programowania zwinnego dla inżynierii oprogramowania. Rozdział ten został dogłębnie zmieniony w stosunku do poprzednich wydań, skupia się na programowaniu zwinnym z użyciem Scrum i omówieniu praktyk zwinnych, takich jak historyjki do definiowania wymagań i programowanie sterowane testami.

Pozostałe rozdziały w tej części są rozwiniętymi omówieniami działań wchodzących w skład procesów wytwarzania oprogramowania, które zostały przedstawione w rozdziale 2. Tematyką rozdziału 4 jest niezwykle ważne zagadnienie inżynierii wymagań, gdzie zdefiniowane są wymagania dotyczące tego, co system ma robić. Rozdział 5 wyjaśnia modelowanie systemów przy użyciu UML. Koncentruję się tu na wykorzystaniu diagramów przypadków użycia, diagramów klas, diagramów przebiegu oraz stanowych do modelowania systemu oprogramowania. W rozdziale 6 omawiam ważność architektury oprogramowania i wykorzystanie wzorców architektonicznych w projektowaniu oprogramowania.

Rozdział 7 wprowadza tematykę projektowania obiektowego i wykorzystanie wzorców projektowych. Włączyłem tu również ważne zagadnienia implementacyjne: ponowne użycie kodu, zarządzanie konfiguracją oraz skrośne wytwarzanie oprogramowania i omówienie programowania otwartego (open source). Rozdział 8 koncentruje się na testowaniu oprogramowania, poczynając od testów jednostkowych podczas tworzenia systemu po testowanie wydań oprogramowania. Zawiera też wykorzystanie programowania sterowanego testami – podejścia, które wywodzi się z metodyk zwinnych, ale ma szerokie możliwości stosowania. Końcowy rozdział 9 zawiera przegląd problemów związanych z ewolucją oprogramowania. Omawiam w nim procesy ewolucji, konserwację oprogramowania oraz zarządzanie systemami odziedziczonymi.

1.
Wprowadzenie

1.1.2 Różnorodność inżynierii oprogramowania

Inżynieria oprogramowania jest systematycznym podejściem do produkcji oprogramowania, uwzględniającym praktyczne zagadnienia związane z kosztami, terminami i rzetelnością wraz z potrzebami klientów i producentów. Użycie konkretnych metodyk, narzędzi i technik zależy od firmy tworzącej oprogramowanie, typu tego oprogramowania oraz ludzi zaangażowanych w proces wytwarzania. Nie istnieją uniwersalne metodyki inżynierii oprogramowania, które byłyby odpowiednie dla wszystkich systemów i wszystkich firm. Zamiast tego w ciągu minionych 50 lat wyewoluowały najrozmaitsze narzędzia i metodyki. Tym niemniej inicjatywa SEMAT [Jacobson i in., 2013] sugeruje, że może istnieć fundamentalny metaproces, którego egzemplarze pozwolą tworzyć procesy różnych rodzajów. Koncepcja ta jest jeszcze we wczesnej fazie rozwoju, ale może się okazać punktem wyjścia dla usprawnienia bieżących metodyk inżynierii oprogramowania.

Zapewne najbardziej znaczącym czynnikiem przy ustalaniu najwłaściwszych metodyk i technik inżynierii oprogramowania jest typ tworzonej aplikacji. Istnieje wiele różnych typów aplikacji, w tym:

Samodzielne aplikacje. Są to programy uruchamiane na komputerach osobistych lub aplikacje działające na urządzeniu mobilnym. Zawierają całą niezbędną funkcjonalność i mogą nie potrzebować połączenia z siecią. Przykładami tego typu aplikacji są programy biurowe dla komputerów osobistych, programy CAD, oprogramowanie do edycji zdjęć, aplikacje podróżne, programy wspierające produktywność itd.

Interaktywne aplikacje transakcyjne. Są to programy wykonywane na komputerze zdalnym, do których użytkownicy uzyskują dostęp ze swoich własnych komputerów, telefonów lub tabletów. Do tej kategorii należą oczywiście aplikacje WWW, takie jak rozwiązania e-commerce, w których wykorzystujemy zdalny system do kupowania towarów i usług. Ta klasa aplikacji obejmuje też systemy biznesowe, w których przedsiębiorstwo zapewnia dostęp do swojego systemu przez przeglądarkę WWW lub specjalizowany program kliencki, a także usługi w chmurze, takie jak poczta elektroniczna i udostępnianie zdjęć. Interaktywne aplikacje zwykle zawierają wielkie składowisko danych, które jest aktualizowane w każdej transakcji.

Wbudowane systemy sterujące. Są to programowe systemy sterujące i zarządzające urządzeniami sprzętowymi. Ujmując liczbowo, zapewne istnieje więcej systemów wbudowanych niż jakiegokolwiek innego rodzaju oprogramowania. Przykłady systemów wbudowanych obejmują oprogramowanie telefonów komórkowych, programy kontrolujące systemy przeciwdziałające blokowaniu się kół w samochodzie (ABS) i oprogramowanie kuchenki mikrofalowej sterujące procesem gotowania.

Systemy przetwarzania wsadowego. Są to systemy biznesowe zaprojektowane do przetwarzania danych w wielkich porcjach (wsadach). Przetwarzają one wielką liczbę indywidualnych danych wejściowych w celu utworzenia odpowiednich danych wyjściowych. Przykładami systemów wsadowych są okresowo działające systemy rozrachunkowe, takie jak telefoniczne systemy bilingowe czy systemy płacowe.

Systemy rozrywkowe. Są to programy do użytku osobistego zaprojektowane w celu zapewnienia rozrywki użytkownika. Większość tych systemów to gry jakiegoś rodzaju, które mogą działać na specjalizowanej konsoli sprzętowej. Najważniejszą wyróżniającą cechą systemów rozrywkowych jest oferowana przez nie jakość interakcji z użytkownikiem.

Systemy do modelowania i symulacji. Są to systemy opracowywane przez naukowców i inżynierów w celu modelowania procesów fizycznych lub sytuacji, w których występuje wiele oddzielnych, oddziałujących ze sobą obiektów. Programy takie są często bardzo wymagające obliczeniowo i do działania wymagają wysokowydajnych systemów równoległych.

Systemy gromadzenia i analizowania danych. Systemy gromadzenia danych to rozwiązania zbierające informacje ze środowiska i przesyłające te dane do innych systemów w celu przetworzenia. Oprogramowanie może musieć współdziałać z czujnikami i często jest instalowane w nieprzyjaznym środowisku, na przykład wewnątrz silnika lub w lokalizacji zdalnej. Analizy big data mogą wykorzystywać chmurowe systemy wykonujące analizy statystyczne i wyszukujące zależności w zgromadzonych danych.

Systemy systemów. Są to rozwiązania używane w przedsiębiorstwach i innych wielkich firmach, złożone z wielu innych systemów oprogramowania. Niektóre mogą być produktami powszechnego stosowania, takie jak systemy ERP. Inne elementy takiego zestawu mogą być napisane specjalnie dla określonego środowiska.

Granice między poszczególnymi typami systemów oczywiście nie są ostre. Jeśli tworzymy grę na telefon komórkowy, musimy wziąć pod uwagę takie same ograniczenia (zasilanie, interakcja ze sprzętem) jak twórcy oprogramowania systemowego tego telefonu. Systemy przetwarzania wsadowego są często używane w połączeniu z internetowymi systemami transakcyjnymi. Na przykład roszczenia dotyczące kosztów podróży w przedsiębiorstwie mogą być zgłaszane przez aplikację WWW, ale przetwarzane w aplikacji wsadowej na potrzeby miesięcznych rozliczeń.

Każdy typ systemu wymaga specjalizowanych technik inżynierii oprogramowania, gdyż samo to oprogramowanie ma odmienne cechy. Na przykład wbudowany system sterujący dla samochodu jest oprogramowaniem krytycznym ze względów bezpieczeństwa i zostaje zapisany w ROM (pamięci tylko do odczytu) przy instalowaniu w pojeździe. Z tego względu jego zmiana jest bardzo kosztowna. Taki system wymaga rozległej weryfikacji i walidacji, aby zminimalizować ryzyko konieczności wzywania samochodów do serwisu w celu rozwiązania problemów z oprogramowaniem. Interakcja z użytkownikiem jest minimalna (a być może w ogóle nie istnieje), nie ma zatem potrzeby wykorzystywania procesu wytwarzania, który jest oparty na prototypowaniu interfejsu użytkownika.

W przypadku interaktywnych systemów internetowych lub aplikacji najlepszym podejściem jest tworzenie i dostarczanie iteracyjne, przy czym system składany jest z komponentów wielokrotnego użycia. Jednak takie podejście może być niepraktyczne dla systemu systemów, w którym interakcje między poszczególnymi systemami muszą zostać wyspecyfikowane z góry, aby każdy system mógł zostać utworzony oddzielnie.

Niemniej jednak istnieją podstawowe zasady inżynierii oprogramowania, które mają zastosowanie do wszystkich typów oprogramowania:

Powinny być rozwijane przy użyciu zarządzanego i zrozumiałego procesu wytwarzania. Firma wytwarzająca oprogramowanie powinna zaplanować proces wytwarzania i mieć jasną wizję tego, co zostanie wyprodukowane i kiedy to będzie gotowe. Konkretny użyty proces zależy oczywiście od typu tworzonego oprogramowania.

Niezawodność i wydajność są istotne dla wszystkich typów systemów. Oprogramowanie powinno zachowywać się zgodnie z oczekiwaniem, bez awarii i powinno być dostępne do użycia, gdy będzie potrzebne. Powinno być bezpieczne ze względu na swoje własne działanie i zostać zabezpieczone przed zewnętrznym atakiem w takim stopniu, jak to tylko możliwe. System powinien działać efektywnie i nie powinien marnować zasobów.

Ważne jest zrozumienie i nadzorowanie specyfikacji i wymagań oprogramowania (czyli co to oprogramowanie powinno robić). Musimy wiedzieć, czego od tworzonego systemu będą oczekiwać różni klienci i użytkownicy i musimy spełnić ich oczekiwania tak, by móc dostarczyć działający, użyteczny system w ramach budżetu i zgodnie z harmonogramem.

Należy efektywnie wykorzystywać dostępne zasoby. Oznacza to, że jeśli jest to właściwe, należy raczej ponownie wykorzystać już napisane oprogramowanie, niż pisać nowe.

Te fundamentalne pojęcia procesu wytwarzania, niezawodności, wymagań, zarządzania i ponownego użycia stanowią osnowę całej tej książki. Są one w różny sposób odzwierciedlane w różnych metodykach, ale leżą u podstaw całego profesjonalnego wytwarzania oprogramowania.

Podstawy te nie zależą od języka używanego do budowania oprogramowania. W tej książce nie zajmuję się szczegółowymi technikami programistycznymi, gdyż różnią się one znacznie w zależności od typu systemu. Na przykład język dynamiczny, taki jak Ruby, jest właściwym typem języka przy tworzeniu systemu interaktywnego, ale zupełnie nieodpowiednim dla inżynierii systemów wbudowanych.