Po fazie analizy, model koncepcyjny jest dalej rozwijany do modelu obiektowego przy użyciu projektowania obiektowego (OOD). W OOD, niezależne od technologii koncepcje w modelu analitycznym są mapowane na klasy wykonawcze, identyfikowane są ograniczenia i projektowane są interfejsy, w wyniku czego powstaje model dla domeny rozwiązania. W skrócie, budowany jest szczegółowy opis określający, jak system ma być zbudowany w oparciu o konkretne technologie
Etapy projektowania zorientowanego obiektowo można określić jako –
- Definicja kontekstu systemu
- Projektowanie architektury systemu
- Identyfikacja obiektów w systemie
- Konstrukcja modeli projektowych
- Specyfikacja interfejsów obiektów
Projektowanie systemu
Projektowanie systemu zorientowanego obiektowoProjektowanie systemów zorientowanych obiektowo polega na określeniu kontekstu systemu, a następnie zaprojektowaniu architektury systemu.
-
Kontekst – Kontekst systemu składa się z części statycznej i dynamicznej. Kontekst statyczny systemu jest projektowany przy użyciu prostego schematu blokowego całego systemu, który jest rozbudowywany do hierarchii podsystemów. Model podsystemów jest reprezentowany przez pakiety UML. Kontekst dynamiczny opisuje sposób interakcji systemu z otoczeniem. Modeluje się go za pomocą diagramów przypadków użycia.
-
Architektura systemu – Architektura systemu jest projektowana na podstawie kontekstu systemu zgodnie z zasadami projektowania architektonicznego, jak również wiedzy dziedzinowej. Zazwyczaj system jest dzielony na warstwy, a każda warstwa jest dekomponowana w celu utworzenia podsystemów.
Object-Oriented Decomposition
Dekompozycja oznacza podział dużego złożonego systemu na hierarchię mniejszych komponentów o mniejszej złożoności, na zasadach divide-and-conquer. Każdy główny składnik systemu nazywany jest podsystemem. Dekompozycja obiektowa identyfikuje poszczególne autonomiczne obiekty w systemie oraz komunikację między tymi obiektami.
Zaletami dekompozycji są –
-
Poszczególne komponenty mają mniejszą złożoność, a więc są bardziej zrozumiałe i łatwiejsze do zarządzania.
-
Umożliwia podział siły roboczej posiadającej specjalistyczne umiejętności.
-
Pozwala na wymianę lub modyfikację podsystemów bez wpływu na inne podsystemy.
Identyfikacja współbieżności
Współbieżność pozwala na otrzymywanie zdarzeń przez więcej niż jeden obiekt w tym samym czasie i jednoczesne wykonywanie więcej niż jednej czynności. Współbieżność jest identyfikowana i reprezentowana w modelu dynamicznym.
Aby umożliwić współbieżność, każdemu współbieżnemu elementowi przypisywany jest oddzielny wątek sterowania. Jeśli współbieżność jest na poziomie obiektu, to dwa współbieżne obiekty mają przypisane dwa różne wątki sterowania. Jeśli dwie operacje jednego obiektu są współbieżne w naturze, to ten obiekt jest podzielony między różne wątki.
Współbieżność jest związana z problemami integralności danych, impasu i głodu. Tak więc jasna strategia musi być wykonana w każdym przypadku, gdy wymagana jest współbieżność. Poza tym współbieżność wymaga identyfikacji na samym etapie projektowania i nie może być pozostawiona na etapie implementacji.
Identyfikacja wzorców
Podczas projektowania aplikacji przyjmuje się pewne powszechnie akceptowane rozwiązania dla niektórych kategorii problemów. Są to właśnie wzorce projektowe. Wzorzec może być zdefiniowany jako udokumentowany zestaw bloków konstrukcyjnych, które mogą być używane w pewnych typach problemów związanych z tworzeniem aplikacji.
Niektóre powszechnie stosowane wzorce projektowe to –
- Wzorzec fasady
- Wzorzec separacji widoku modelu
- Wzorzec obserwatora
- Wzorzec kontrolera widoku modelu
- Wzorzec publikuj subskrybuj
- Wzorzec proxy
.
Kontrolowanie zdarzeń
Podczas projektowania systemu, należy zidentyfikować zdarzenia, które mogą wystąpić w obiektach systemu i odpowiednio się nimi zająć.
Zdarzenie to specyfikacja istotnego zdarzenia, które ma lokalizację w czasie i przestrzeni.
Istnieją cztery typy zdarzeń, które mogą być modelowane, a mianowicie –
-
Zdarzenie sygnalizacyjne – nazwany obiekt rzucany przez jeden obiekt i przechwytywany przez inny obiekt.
-
Zdarzenie wywołania – zdarzenie synchroniczne reprezentujące wysłanie operacji.
-
Zdarzenie czasowe – Zdarzenie reprezentujące upływ czasu.
-
Zdarzenie zmiany – Zdarzenie reprezentujące zmianę stanu.
Obsługa warunków brzegowych
Faza projektowania systemu musi dotyczyć inicjalizacji i zakończenia systemu jako całości, jak również każdego podsystemu. Różne aspekty, które są dokumentowane są następujące –
-
Rozruch systemu, tj. przejście systemu ze stanu niezainicjowanego do stanu ustalonego.
-
Zakończenie systemu, tj, zamknięcie wszystkich uruchomionych wątków, wyczyszczenie zasobów oraz komunikatów do wysłania.
-
Wstępna konfiguracja systemu oraz rekonfiguracja systemu w razie potrzeby.
-
Przewidywanie awarii lub niepożądanego zakończenia systemu.
Warunki brzegowe są modelowane przy użyciu brzegowych przypadków użycia.
Projektowanie obiektów
Po opracowaniu hierarchii podsystemów identyfikowane są obiekty w systemie i projektowane są ich szczegóły. Tutaj projektant uszczegóławia strategię wybraną podczas projektowania systemu. Nacisk przesuwa się z koncepcji domeny aplikacji w kierunku koncepcji komputerowych. Obiekty zidentyfikowane podczas analizy są wyryte do implementacji w celu zminimalizowania czasu wykonania, zużycia pamięci i ogólnego kosztu.
Projektowanie obiektów obejmuje następujące fazy –
- identyfikacja obiektów
- reprezentacja obiektów, tj, budowa modeli projektowych
- Klasyfikacja operacji
- Projektowanie algorytmów
- Projektowanie relacji
- Implementacja sterowania dla zewnętrznych interakcji
- Pakowanie klas i asocjacji w moduły
Identyfikacja obiektów
Pierwszym etapem projektowania obiektowego jest identyfikacja obiektów. Obiekty zidentyfikowane w fazach analizy obiektowej są grupowane w klasy i udoskonalane tak, aby nadawały się do rzeczywistej implementacji.
Funkcje tego etapu to –
-
Identyfikacja i udoskonalanie klas w każdym podsystemie lub pakiecie
-
Definiowanie powiązań i asocjacji między klasami
-
Projektowanie hierarchicznych asocjacji między klasami, tj, generalizacja/specjalizacja i dziedziczenie
-
Projektowanie agregacji
Object Representation
Po zidentyfikowaniu klas należy je reprezentować za pomocą technik modelowania obiektowego. Etap ten polega zasadniczo na konstruowaniu diagramów UML.
Istnieją dwa rodzaje modeli projektowych, które należy wytworzyć –
-
Modele statyczne – Opisanie statycznej struktury systemu za pomocą diagramów klas i diagramów obiektów.
-
Modele dynamiczne – Do opisania dynamicznej struktury systemu i pokazania interakcji między klasami przy użyciu diagramów interakcji i diagramów diagramów stanów.
Klasyfikacja operacji
W tym kroku operacje, które mają być wykonywane na obiektach, są definiowane przez połączenie trzech modeli opracowanych w fazie OOA, a mianowicie modelu obiektowego, modelu dynamicznego i modelu funkcjonalnego. Operacja określa, co ma być zrobione, a nie jak ma być zrobione.
W zakresie operacji wykonywane są następujące zadania –
-
Opracowywany jest diagram przejść stanów każdego obiektu w systemie.
-
Operacje są definiowane dla zdarzeń odbieranych przez obiekty.
-
Identyfikowane są przypadki, w których jedno zdarzenie wywołuje inne zdarzenia w tych samych lub różnych obiektach.
-
Identyfikowane są podoperacje w ramach akcji.
-
Główne akcje są rozszerzane do diagramów przepływu danych.
Projektowanie algorytmów
Operacje w obiektach są definiowane za pomocą algorytmów. Algorytm to stopniowa procedura, która rozwiązuje problem określony w operacji. Algorytmy skupiają się na tym, jak to ma być zrobione.
Może istnieć więcej niż jeden algorytm odpowiadający danej operacji. Po zidentyfikowaniu alternatywnych algorytmów wybierany jest algorytm optymalny dla danej dziedziny problemowej. Metryki wyboru optymalnego algorytmu to –
-
Złożoność obliczeniowa – Złożoność określa efektywność algorytmu pod względem czasu obliczeń i zapotrzebowania na pamięć.
-
Elastyczność – Elastyczność określa, czy wybrany algorytm może być odpowiednio zaimplementowany, bez utraty adekwatności w różnych środowiskach.
-
Zrozumiałość – Określa, czy wybrany algorytm jest łatwy do zrozumienia i implementacji.
Projektowanie relacji
Strategia implementacji relacji musi być opracowana w fazie projektowania obiektu. Główne relacje, którymi się zajmujemy, obejmują asocjacje, agregacje i dziedziczenie.
Projektant powinien wykonać następujące czynności dotyczące asocjacji –
-
Zidentyfikować, czy asocjacja jest jednokierunkowa czy dwukierunkowa.
-
Analizuje ścieżkę asocjacji i aktualizuje je w razie potrzeby.
-
Wdraża asocjacje jako odrębny obiekt, w przypadku relacji wiele do wielu; lub jako link do innego obiektu w przypadku relacji jeden do jednego lub jeden do wielu.
W odniesieniu do dziedziczenia, projektant powinien wykonać następujące czynności –
-
Dostosować klasy i ich asocjacje.
-
Identyfikować klasy abstrakcyjne.
-
Postanowienia, aby zachowania były współdzielone w razie potrzeby.
Implementacja sterowania
Projektant obiektów może włączyć udoskonalenia w strategii modelu diagramu stanów. W projektowaniu systemu wykonuje się podstawową strategię realizacji modelu dynamicznego. Podczas projektowania obiektów, strategia ta jest trafnie upiększana w celu odpowiedniej implementacji.
Podejścia do implementacji modelu dynamicznego są następujące –
-
Represent State as a Location within a Program – Jest to tradycyjne podejście oparte na procedurach, w którym miejsce sterowania definiuje stan programu. Maszyna stanów skończonych może być zaimplementowana jako program. Przejście tworzy instrukcję wejściową, główna ścieżka sterowania tworzy sekwencję instrukcji, rozgałęzienia tworzą warunki, a ścieżki wsteczne tworzą pętle lub iteracje.
-
Maszyna stanów – To podejście bezpośrednio reprezentuje maszynę stanów poprzez klasę silnika maszyny stanów. Klasa ta wykonuje maszynę stanów poprzez zestaw przejść i akcji dostarczonych przez aplikację.
-
Kontrola jako współbieżne zadania – W tym podejściu obiekt jest implementowany jako zadanie w języku programowania lub systemie operacyjnym. Tutaj, zdarzenie jest zaimplementowane jako wywołanie międzyzadaniowe. Zachowuje to wrodzoną współbieżność rzeczywistych obiektów.
Pakowanie klas
W każdym dużym projekcie ważne jest skrupulatne dzielenie implementacji na moduły lub pakiety. Podczas projektowania obiektów, klasy i obiekty są grupowane w pakiety, aby umożliwić wielu grupom współpracę nad projektem.
Różne aspekty pakowania to –
-
Ukrycie wewnętrznych informacji przed widokiem z zewnątrz – Pozwala to na postrzeganie klasy jako „czarnej skrzynki” i pozwala na zmianę implementacji klasy bez wymagania od klientów klasy modyfikacji kodu.
-
Spójność elementów – Element, taki jak klasa, operacja lub moduł, jest spójny, jeśli jest zorganizowany na spójnym planie, a wszystkie jego części są wewnętrznie powiązane tak, że służą wspólnemu celowi.
-
Konstrukcja modułów fizycznych – Przy konstruowaniu modułów fizycznych pomocne są następujące wskazówki –
-
Klasy w module powinny reprezentować podobne rzeczy lub komponenty w tym samym obiekcie złożonym.
-
Klasy blisko powiązane powinny znajdować się w tym samym module.
-
Klasy niepowiązane lub słabo powiązane powinny być umieszczone w oddzielnych modułach.
-
Moduły powinny mieć dobrą spójność, tzn, wysoką współpracę między jego komponentami.
-
Moduł powinien mieć niskie sprzężenie z innymi modułami, tzn. interakcja lub współzależność między modułami powinna być minimalna.
-
Optymalizacja projektu
Model analityczny przechwytuje logiczną informację o systemie, podczas gdy model projektowy dodaje szczegóły, aby wspierać efektywny dostęp do informacji. Zanim projekt zostanie zaimplementowany, powinien zostać zoptymalizowany tak, aby implementacja była bardziej efektywna. Celem optymalizacji jest zminimalizowanie kosztów w kategoriach czasu, przestrzeni i innych metryk.
Jednakże optymalizacja projektu nie powinna być nadmiarem, ponieważ łatwość implementacji, łatwość utrzymania i rozszerzalność są również ważnymi kwestiami. Często widać, że doskonale zoptymalizowany projekt jest bardziej wydajny, ale mniej czytelny i nadający się do ponownego użycia. Więc projektant musi znaleźć równowagę między tymi dwoma.
Różne rzeczy, które można zrobić w celu optymalizacji projektu to –
- Dodaj zbędne asocjacje
- Opuszczanie nieużytecznych asocjacji
- Optymalizacja algorytmów
- Zapisywanie atrybutów pochodnych w celu uniknięcia ponownego obliczania złożonych wyrażeń
Dodawanie zbędnych asocjacji
Podczas optymalizacji projektu, sprawdzane jest, czy wyprowadzanie nowych asocjacji może zmniejszyć koszty dostępu. Chociaż te nadmiarowe asocjacje mogą nie dodawać żadnych informacji, mogą zwiększyć wydajność całego modelu.
Dodawanie nieużytecznych asocjacji
Obecność zbyt wielu asocjacji może sprawić, że system stanie się nieczytelny, a tym samym zmniejszy ogólną wydajność systemu. Tak więc, podczas optymalizacji, wszystkie nieużyteczne asocjacje są usuwane.
Optymalizacja algorytmów
W systemach zorientowanych obiektowo optymalizacja struktury danych i algorytmów odbywa się w sposób zespołowy. Gdy projekt klasy jest już na miejscu, operacje i algorytmy muszą być zoptymalizowane.
Optymalizację algorytmów uzyskuje się przez –
- Odwrócenie kolejności wykonywania zadań obliczeniowych
- Odwrócenie kolejności wykonywania pętli od tej ustalonej w modelu funkcjonalnym
- Usuwanie martwych ścieżek w algorytmie
.
Zapisywanie i przechowywanie atrybutów pochodnych
Atrybuty pochodne to atrybuty, których wartości są obliczane jako funkcje innych atrybutów (atrybutów bazowych). Ponowne obliczanie wartości atrybutów pochodnych za każdym razem, gdy są one potrzebne, jest czasochłonną procedurą. Aby tego uniknąć, wartości mogą być obliczane i przechowywane w ich obliczonych postaciach.
Jednakże może to powodować anomalie aktualizacji, tj. zmianę wartości atrybutów bazowych bez odpowiadającej jej zmiany wartości atrybutów pochodnych. Aby tego uniknąć, podejmowane są następujące kroki –
-
Przy każdej aktualizacji wartości atrybutu bazowego atrybut pochodny jest również ponownie obliczany.
-
Wszystkie atrybuty pochodne są ponownie obliczane i aktualizowane okresowo w grupie, a nie po każdej aktualizacji.
Dokumentacja projektowa
Dokumentacja jest istotną częścią każdego procesu tworzenia oprogramowania, która rejestruje procedurę tworzenia oprogramowania. Decyzje projektowe muszą być udokumentowane dla każdego nietrywialnego systemu oprogramowania w celu przekazania projektu innym.
Obszary zastosowań
Choć jest to produkt drugorzędny, dobra dokumentacja jest niezbędna, szczególnie w następujących obszarach –
- W projektowaniu oprogramowania, które jest tworzone przez wielu programistów
- W iteracyjnych strategiach rozwoju oprogramowania
- W tworzeniu kolejnych wersji projektu oprogramowania
- Do oceny oprogramowania
- Do znajdowania warunków i obszarów testowania
- Do konserwacji oprogramowania.
Zawartość
Korzystna dokumentacja powinna zasadniczo zawierać następującą zawartość –
-
Architektura systemu wysokiego poziomu – Diagramy procesów i diagramy modułów
-
Kluczowe abstrakcje i mechanizmy – Diagramy klas i diagramy obiektów.
-
Scenariusze ilustrujące zachowanie głównych aspektów – Diagramy behawioralne
Cechy
Cechy dobrej dokumentacji to –
-
Precyzyjna i jednocześnie jednoznaczna, spójna i kompletna
-
Śledzalna ze specyfikacją wymagań systemu
-
Dobrze ustrukturyzowana
-
Diagramatyczna zamiast opisowej
.