Spis treści
Łączenie komponentów
Tworząc architekturę, należy zastanowić się, w jaki sposób połączyć ze sobą komponenty. Pomocne są w tym następujące zasady:
- Zasada zależności niecyklicznych.
- Zasada stabilnych zależności.
- Zasada stabilnych abstrakcji.
Zasada zależności niecyklicznych
Nie dopuść do powstania cyklicznych związków w diagramie zależności komponentów.
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 132.
Zmniejsza to zależność jednych komponentów od drugich — sprawia, że nasz komponent zależy od mniejszej liczby komponentów — łatwiej jest go przetestować oraz rozwijać — wystarczy skompilować nasz komponent i zależne od niego. Zależności cykliczne rodzą problemy z równoległym rozwijaniem komponentów przez kilku programistów, koniecznością kompilowania większej liczby komponentów, konieczność integrowania się i testowania integracji z większą liczbą komponentów.
Cykl można usunąć w następujący sposób:
- Zastosować zasadę DIP — wystawić interfejs w naszym komponencie, aby odwrócić zależność — teraz to ten drugi komponent będzie zależny od naszego.
- Utworzyć nowy komponent, od którego będziemy zależni my i inny komponent, do którego chcieliśmy dodać kłopotliwy kod.
SDP — Zasada stabilnych zależności (ang. Stable Dependencies Principle)
Zależność kieruj w stronę elementu stabilnego.
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 139.
Oprogramowanie tworzone na podstawie tej zasady sprawia, że komponenty mające być łatwe do zmodyfikowania, nie zależą od komponentów stabilnych. Komponent stabilny to taki, w którym trzeba wykonać dużo pracy, aby go zmodyfikować (wpływ on na wiele innych komponentów).
Przykład:
- Komponent stabilny — Od naszego komponentu zależą trzy inne (używają naszego komponentu), lecz on sam nie zależy od żadnego innego. Nasz komponent jest odpowiedzialny za pozostałe trzy komponenty. Jest on stabilny (ciężko go zmienić), odpowiedzialny i niezależny. Jego miara I = 0 (o miarach piszę niżej).
- Komponent niestabilny — Od naszego komponentu nic nie zależy (nikt go nie używa), lecz nasz komponent zależy od trzech innych (używa ich). Jest on niestabilny (łatwo go zmienić, bo wystarczy zmienić tylko go, nie trzeba zmieniać innych komponentów), nieodpowiedzialny (nie jest odpowiedzialny za żaden inny komponent) i zależny. Jego miara I = 1. on I = 1.
SAP — Zasada stabilnych abstrakcji (ang. Stable Abstractions Principle)
Komponent powinien być tak abstrakcyjny, jak jest stabilny.
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 144.
Ta zasada określa relację między stabilnością i abstrakcyjnością. Zasada SDP (Zasada stabilnych zależności) zaleca tworzyć zależności w stronę stabilności, zaś zasada SAP (Zasada stabilnych abstrakcji) określa, że stabilność implikuje w abstrakcji. Z tych zasad mamy zasadę DIP (Zasada odwrócenia zależności) dla komponentów, która zaleca kierować zależności w stronę abstrakcji.
Miara stabilności
Zdefiniujmy miarę niestabilności (ang. Instability):
I = Fan-Out / (Fan-In + Fan-Out),
gdzie:
- I = niestabilność komponentu. I = 1 -> maksymalnie niestabilny, I = 0 -> maksymalnie stabilny.
- Fan-Out = liczba klas w naszym komponencie zależących od klas spoza komponentu.
- Fan-In = liczba klas spoza naszego komponentu zależących od klas z naszego komponentu
Zgodnie z zasadą SDP (Zasada stabilnych zależności) I naszego komponentu powinna być większa, niż miary I komponentów, od których nasz komponent zależy. Miara I powinna zmniejszać się zgodnie z kierunkiem zależności.
Miara abstrakcji
Zdefiniujmy miarę abstrakcji komponentu:
A = Na / Nc,
gdzie:
- A = abstrakcyjność komponentu. A = 0 -> minimalnie abstrakcyjny (nie ma żadnej abstrakcyjnej klasy), A = 1 -> maksymalnie abstrakcyjny (wszystkie klasy są abstrakcyjne).
- Nc — liczba wszystkich klas w komponencie.
- Na — liczba wszystkich klas abstrakcyjnych i interfejsów w komponencie.
Ciąg główny
Warto jest zaobserwować związek między stabilnością (I) oraz abstrakcyjnością (A).
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 147 — Rysunek 14.13 — Strefy bólu.
Na powyższym obrazku przedstawiono na osiach obie miary: miarę niestabilności oraz abstrakcyjności. Ciąg główny to odcinek łączący punkty (1,0) i (0,1) (I, A). Umieszczenie komponentów w punktach początku i końca ciągu głównego jest najbardziej pożądane. Na rysunku widać również:
- Strefa bólu, czyli maksymalnie konkretne i stabilne komponenty — nie chcemy takich, bo ciężko je zmienić (są sztywne).
- Strefa bezużyteczności, czyli maksymalnie abstrakcyjne komponenty, których nikt nie używa (należy do wyrzucenia).
Bardzo ciężko jest stworzyć komponenty, które będą na początku i końcu ciągu głównego. Warto jest je jednak umieszczać na ciągu głównym, dlatego zdefiniujmy pomocniczą miarę: odległość od ciągu głównego (D):
D = | A + I -1 |,
gdzie:
- D = 1 -> maksymalne oddalenie od ciągu głównego, D = 1 -> jest na ciągu głównym.
- A — miara abstrakcyjności komponentu.
- I — miara niestabilności komponentu.
- D — odległość od ciągu głównego.
Możemy również policzyć średnią oraz odchylenia standardowe naszych komponentów. Jeżeli komponent jest dalej niż odchylenie standardowe od ciągu głównego, to warto mu się przyjrzeć i zrobić refaktoryzację.
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 149 — Rysunek 14.14 — Wykres punktowy komponentów.
Źródło: Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin. — s. 150 — Rysunek 14.15 — Wykres zmian wartości D dla jednego komponentu w czasie.
Możemy też umieszczać wartość D na osi czasu i obserwować jak kolejne działania oddalają lub zbliżają nas do ciągu głównego oraz zareagować, gdy nasz komponent oddali się od niego za bardzo. Należy pamiętać, że struktury zależności komponentów nie da się zaprojektować od początku do końca. Ewoluuje ona w czasie rozrastania się systemu i wciąż zmienia. Warto więc zdefiniować miary i proces ciągłego obserwowania ich, aby reagować, gdy nasza architektura zaczyna odbiegać od naszej wizji.
Wszystkie posty związane z mini projektem: Budowa czystej architektury:
- Początek mini projektu: Budowa czystej architektury
- Architektura
- Paradygmaty programowania
- Zasady SOLID w kontekście architektury
- Spójność komponentów
- Łączenie komponentów
- Struktura oprogramowania
- Zasady i poziomy
- Czysta architektura
- Budowanie Czystej architektury
- Podsumowanie projektu: Budowanie czystej architektury
- Moje notatki z nauki szybkiego czytania
Źródła
Obrazy
Materiały
- Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin.
We wzorze na niestabilność, w mianowniku powinna być suma, a nie różnica. Istnieje możliwość, że zależności wchodzących będzie tyle samo co wychodzących, a to nam da w mianowniku zero.
Racja! Dziękuję!