Łączenie komponentów

przez Karol Bocian | 22 kwietnia, 2022

Łą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:

  1. Zastosować zasadę DIP — wystawić interfejs w naszym komponencie, aby odwrócić zależność — teraz to ten drugi komponent będzie zależny od naszego.
  2. 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:

Źródła

Obrazy

Materiały

  • Czysta architektura. Struktura i design oprogramowania. Przewodnik dla profesjonalistów — Robert C. Martin.
Kategoria: Projekt Budowa czystej architektury

O Karol Bocian

Programowanie i świat agentów programowalnych, który poznał na Wydziale Matematyki i Nauk Informacyjnych, wciągnął go w przemysł IT. W trakcie swojej praktyki zawodowej Karol zrozumiał, że nie ważne co się robi i kim się jest, ale wiedza z zarządzania przydaje się wszędzie. Rozpoczął studia na kierunku Zarządzanie i Inżyniera Produkcji. W przypadku Karola zarządzanie to nie tylko teoria czy praca, ale prawie każdy element jego życia, to jego pasja.

2 komentarze do „Łączenie komponentów

  1. ddosmiko

    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.

Możliwość komentowania została wyłączona.