1
Inżynieria oprogramowania
wykład 11
Zasady projektowania oprogramowania
2/26
Informacje podstawowe
projektowanie → jedna z najważniejszych
czynności procesu powstawania
oprogramowania, niezależnie od modelu procesu
wytwórczego
projekt → techniczna reprezentacja (model)
budowanego obiektu/systemu
projekt może być porównywany z wymaganiami
użytkownika oraz poddawany kontroli jakości wg
przyjętych kryteriów
3/26
Główne zagadnienia projektu
projekt danych → przetworzenie informacji zawartych w
modelu danych na struktury danych, oparte na opisach
obiektów i związków między nimi
projekt architektury → opis zależności między
najważniejszymi częściami programu, przygotowany na
podstawie specyfikacji wymagań, modelu systemu i
związków między modułami oraz procedurami
projekt interfejsów → metody wymiany informacji między
modułami programu oraz z innymi systemami i
użytkownikami (oparte na diagramach przepływu danych)
projekt modułów i procedur → szczegółowy opis działania
procedur, oparty na specyfikacji przepływu sterowania i
diagramach STD
4/26
Zasady projektowania
oprogramowania
architektura powinna być oparta na łatwych do określenia
wzorcach projektowych, zbudowana z modułów
spełniających kryteria jakości i umożliwiających
implementację i testowanie
projekt powinien cechować się modularnością (opis
podziału na moduły realizujące funkcje i podfunkcje)
oddzielny opis danych, architektury, modułów, interfejsów
struktury danych w projekcie powinny odpowiadać
strukturom obiektów systemu
najlepiej do tworzenia projektów wykorzystywać
sprawdzone metody
projekt powinien być oparty na ustaleniach sporządzonych
na etapie analizy wymagań
5/26
Cechy dobrego projektu
jednorodność i spójność (dobrze opisane
związki między modułami i interfejsami)
struktura projektu powinna ułatwiać
wprowadzanie zmian
projekt powinien uwzględniać możliwość
wystąpienia nieprzewidzianych sytuacji
należy regularnie dokonywać oceny jakości
projektu i poddawać przeglądom (w celu
uniknięcia błędów, zgodność z założeniami)
6/26
Pojęcia związane z projektowaniem
abstrakcja
uściślanie
modularność
architektura oprogramowania
hierarchia sterowania
dzielenie na części
struktury danych
procedury
ukrywanie informacji
7/26
Abstrakcja
definicja
uproszczenie rozpatrywanego problemu, polegające na ograniczeniu
zakresu cech manipulowanych obiektów wyłącznie do cech kluczowych
dla algorytmu, a jednocześnie niezależnych od implementacji (wg
pl.wikipedia.org)
pozwala rozważać problemy na wybranym poziomie szczegółowości, bez
wnikania w nieistotne szczegóły (A.Wasserman: Principles of systematic
data design and implementation, Software design techniques, IEEE
Computer SocietyPress, 1983)
rodzaje
abstrakcja proceduralna → nazwany ciąg zadań, pozwalający wykonać
pewne zadanie
abstrakcja danych → nazwany zestaw informacji opisujących obiekt
danych, języki programowania udostępniają możliwość definiowania
abstrakcyjnych typów danych (szablony)
abstrakcja przepływu sterowania → opis sterowania bez szczegółów
8/26
Uściślanie
jest procesem wyjaśniania działania programu
jest metodą projektowania typu „od ogółu do
szczegółu”
polega na stopniowym zmniejszaniu poziomu
abstrakcji poprzez uściślanie i dekompozycję aż
do instrukcji w języku programowania
(najniższy poziom) *
uściślanie i abstrakcja uzupełniają się
wzajemnie
* N. Wirth: Program development by stepwise refinement, CACM, 1971
9/26
Modularność
podział programu na moduły – oddzielne składniki realizujące pewne
zadania, ale tworzące razem spójną całość
podejście człowieka do rozwiązywania problemów
wykorzystuje się tu metodę „dziel i zwyciężaj” – skomplikowany
problem łatwiej rozwiązać dzieląc go na mniejsze (przykład:
rekurencja – sortowanie przez scalanie oraz szybkie, wyszukiwanie
połówkowe), typowe podejście człowieka: złożony problem
składający się z połączonych podproblemów wydaje się bardziej
trudny do rozwiązania niż podproblemy oddzielnie
dzielenie programu na moduły ma sens ale tylko w pewnym zakresie
10/26
Wpływ modularności na koszty
tworzenia oprogramowania
zakres minimalnych
kosztów
koszt całkowity
koszt integracji
koszt modułu
liczba modułów
p
ra
c
o
c
h
ło
n
n
o
ś
ć
lu
b
k
o
s
z
t
11/26
Wpływ modularności na koszty
tworzenia oprogramowania - analiza
koszt tworzenia oprogramowania związany z podziałem
na moduły składa się z 2 głównych składników
koszt wytworzenia modułów
koszt integracji modułów
koszt wytworzenia modułów zmniejsza się przy
wzroście liczby modułów, głównie dzięki zmniejszaniu
wielkości modułów
koszt integracji rośnie przy wzroście liczby modułów,
zwiększa się pracochłonności integracji
koszt całkowity posiada pewien optymalny zakres ze
względu na liczbę modułów
należy unikać zbyt małej oraz zbyt dużej liczby
modułów
12/26
Architektura oprogramowania
ogólna struktura oprogramowania i sposób powiązania
części w integralny system *
projekt architektury oprogramowania powinien zawierać: *
cechy strukturalne → składniki systemu (moduły, obiekty,
zapytania), sposoby ich połączenia i wymiany informacji
cechy pozafunkcjonalne → opis wpływu struktury na spełnienie
wymagań związanych z efektywnością, niezawodnością,
bezpieczeństwem, łatwością ewentualnej modyfikacji, itp.
rodziny podobnych systemów → wykorzystanie sprawdzonych
wzorców stosowanych do projektowania podobnych systemów,
uwzględnienie ponownego wykorzystania składników architektury
* M. Show, D. Garlan: Formulations and formalisms in software architecture, Lecture
Notes in Computer Science, Springer-Verlag, 1995
13/26
Modele opisu architektury
oprogramowania
modele strukturalne → opis programu jako zestawu
pewnych składników
modele wzorców → opis systemów na wyższym
poziomie abstrakcji jako struktury składającej się z
wzorców projektowych występujących w podobnych
systemach
modele dynamiczne → opis zmian w strukturze lub
konfiguracji systemu w zależności od zdarzeń
zewnętrznych
modele procesów → projektowanie procesów i
procedur postępowania
modele funkcji → opis hierarchii funkcji realizowanych
przez system
modele mogą być tworzone za pomocą języków opisu architektury (ADL)
14/26
Hierarchia sterowania
nazywana strukturą programu
stanowi opis połączenia modułów programu z którego
wynika hierarchiczna struktura przepływu sterowania
nie uwzględnia: kolejności wykonywanych zadań,
podejmowanych decyzji, operacji wykonywanych
wielokrotnie
sposoby przedstawiania:
diagramy drzewiaste
notacja Warniera-Orra
diagramy Jacksona
15/26
Diagram drzewiasty hierarchii
przepływu sterowania - przykład
M
a
b
e
d
c
f
h
g
i
j
l
k
n
m
o
p
szerokość (zasięg sterowania)
g
łę
b
o
k
o
ś
ć
–
lic
z
b
a
p
o
z
io
m
ó
w
s
te
ro
w
a
n
ia
rozgałęzienie wyjściowe –
liczba wywoływanych
modułów
rozgałęzienie
wejściowe-liczba
modułów
wywołujących
dany moduł
moduł c jest
nadrzędny dla
modułów k i l
16/26
Poziomy i pionowy podział architektury
hierarchicznej na części
poziomy → podział na funkcje wykonujące różne zadania
( np.: wczytywanie danych wejściowych, przetwarzanie
danych, zwracanie, danych wyjściowych), ułatwia
testowanie, pielęgnację, zmniejsza negatywne skutki
błędów, ułatwia rozszerzanie programu
pionowy (faktoryzacja) → podział na moduły na
sterujące (rzadko przetwarzają dane) i „robocze”
(przyjmują dane, przetwarzają i zwracają), pozwala unikać
zbyt wielu skutków ubocznych zmian (zmiany w modułach
podrzędnych powodują małą ilość skutków ubocznych,
zmiany w modułach umiejscowionych wysoko mogą
powodować skutki uboczne w modułach niżej w hierarchii)
17/26
Podział poziomy - przykład
M
a
b
e
d
c
f
h
g
j
l
k
n
m
n
funkcja 1
funkcja 2
funkcja 3
18/26
Podział pionowy - przykład
M
a
b
e
d
c
f
h
g
j
l
k
n
m
n
moduły
sterujące
moduły
„robocze”
19/26
Struktury danych
opis związków logicznych między danymi
określają organizację danych, metody dostępu i
sposoby przetwarzania danych
podstawowe struktury danych
skalary → pojedyncze elementy, dostęp poprzez podanie
adresu w pamięci, rozmiary zależne od środowiska
programistycznego (np. bool = 1B, int=4B itd.)
wektory → ciągi skalarów
tablice → wektory wielowymiarowe
listy → elementami są skalary, wektory lub tablice, w pamięci
niekoniecznie obok siebie, każdy element zawiera właściwe
dane i informacje o położeniu elementu następnego
drzewa → wielokrotnie powiązane listy (struktura
hierarchiczna)
20/26
Procedury
opis sposobu przetwarzania informacji
zawiera: kolejność wykonywania zadań,
miejsca podejmowania decyzji, powtórzenia
wielokrotne czynności, czasem również
używane struktury danych
struktura procedur związana jest z architekturą
programu
projekt procedur powinien zawierać odniesienia
do procedur z modułów podrzędnych
21/26
Ukrywanie informacji
moduły powinny być tak projektowane aby
procedury i dane tego danego moduły były
widoczne dla innych modułów tylko jeżeli jest to
konieczne
uwzględniając powyższe zapobiega się
powstawanie skomplikowanej sieci
niepotrzebnych zależności
korzyści z ukrywania informacji mogą pojawić się
przy wprowadzaniu zmian → skutki
ewentualnych błędów nie wpływają na działanie
całego systemu
22/26
Projektowanie systemów
modularnych
niezależność funkcjonalna → małe moduły, nie
wymieniające zbyt dużej ilości informacji z innymi
modułami, odpowiedzialne za realizację jednej określonej
funkcji systemu, zalety: łatwy podział pracy zespołów,
łatwiejsze testowanie i pielęgnacja (ograniczone skutki
zmian), możliwość wielokrotnego użycia, niezależność
można mierzyć badając spoistość i sprzężenia
spoistość → moduł spoisty odpowiada za realizację
jednego konkretnego zadania i nie wymienia zbyt dużo
informacji z innymi modułami, nie przekłada się jednak
bezpośrednio na jakość projektu
sprzężenia → związki między modułami oprogramowania,
należy unikać zbyt wielu sprzężeń sprzyjających tzw.
przenoszeniu się błędu między modułami
23/26
Rodzaje sprzężeń
brak → moduły podrzędne do różnych modułów nadrzędnych
informacyjne (słabe) → wywołanie modułu podrzędnego wraz
przekazanie pewnej listy argumentów
znacznikowe (słabe) → przekazywane dane mają pewną strukturę
przekazywaną wraz z danymi
sterujące (silniejsze) → przekazywane dane służą wyborowi dalszego
działania, występują bardzo często
zewnętrzne (silne) → powiązanie z urządzeniami zewnętrznymi,
protokołami komunikacyjnymi, itp., powinno być ich jak najmniej
globalne (silne) → moduły korzystają ze wspólnych danych,
przechowywanych np. w pamięci lub plikach dyskowych → trudne
diagnozowanie błędów
zawartości (najsilniejsze) → moduł korzysta z danych
przechowywanych w innym module lub wywołuje jego wewnętrzne
procedury z pominięciem interfejsów → należy ich unikać
24/26
Heurystyka projektowania
modularnego - zasady
zmiana ustalonych struktur powinna powodować zwiększenie
spoistości i unikanie sprzężeń (podział i łączenie modułów w celu
poprawy niezależności funkcjonalnej)
unikanie szerokich rozgałęzień wyjściowych (płaska struktura),
wykorzystywanie rozgałęzień wejściowych na niższych poziomach
hierarchii
zasięg skutków działania modułu (moduły których działanie jest
uzależnione od działań danego modułu) nie powinien przekraczać
zasięgu sterowania (moduły pośrednio lub bezpośrednio podrzędne)
modułu
ograniczanie złożoności i nadmiarowości interfejsów modułów
(przyczyna błędów) i zapewnianie ich spójności
zwiększanie przewidywalności działania modułów (takie same dane
wejściowe powodują otrzymanie zawsze takich samych danych
wyjściowych
unikanie sprzężeń zawartości → łatwiejsza kontrola i pielęgnacja
25/26
Dokumentacja projektowa
zakres prac projektowych → opracowany na podstawie
specyfikacji systemu i specyfikacji wymagań
projekt danych → struktura danych i plików zewnętrznych
projekt architektury → opracowany na podstawie modelu
analitycznego, zawiera diagramy hierarchii modułów
opis interfejsów
opis modułów, procedur i podprocedur
opis składników programu w połączeniu z wymaganiami
(sprawdzenie projektu pod kątem stawianych wymagań i
określenie kluczowych składników dla wymagań)
wstępna wersja zestawu testów
sposób wdrożenia systemu u klienta
dodatkowe dane → opisy algorytmów, zastępcze procedury
działania, wstępna wersja podręcznika użytkownika i inne
istotne
26
Dziękuję za uwagę
źródło: „Praktyczne podejście do inżynierii oprogramowania”, R.S. Pressman