Reference · Glosariusz
Słownictwo skilla codebase-design i wszystkiego, co
z niego korzysta (improve-codebase-architecture).
Terminy używane dokładnie w tym znaczeniu — nie
zamiennie z "komponent", "serwis", "API" czy "granica".
Spójność języka jest tu celem samym w sobie.
Cokolwiek z interfejsem i implementacją. Celowo niezależne od skali — funkcja, klasa, pakiet, albo warstwa przecinająca cały system. Unikaj: unit, component, service.
Wszystko, co musi wiedzieć wywołujący, żeby poprawnie użyć modułu: sygnatura typów, ale też niezmienniki, ograniczenia kolejności, tryby błędów, wymagana konfiguracja, charakterystyka wydajności. Unikaj: API, signature (zbyt wąskie — dotyczą tylko powierzchni na poziomie typów).
Implementacja to co jest w środku modułu. Adapter to konkretna rzecz spełniająca interfejs przy seamie — opisuje rolę (jaki slot wypełnia), nie treść. Mały adapter może mieć dużą implementację (repo Postgresa); duży adapter może mieć małą implementację (fake w pamięci).
Dźwignia przy interfejsie: ile zachowania wywołujący (albo test) może uruchomić za jedną jednostkę interfejsu, którego musi się nauczyć. Moduł jest głęboki, gdy duża ilość zachowania siedzi za małym interfejsem; płytki, gdy interfejs jest niemal tak skomplikowany jak implementacja.
Miejsce, w którym można zmienić zachowanie bez edytowania w tym miejscu — lokalizacja, w której żyje interfejs modułu. Gdzie postawić seam to osobna decyzja projektowa, różna od tego, co za nim stoi. Unikaj: boundary (przeciążone znaczeniem bounded context z DDD).
Leverage to co dostają wywołujący dzięki głębokości: więcej możliwości za jednostkę nauczonego interfejsu — jedna implementacja spłaca się w N miejscach wywołania i M testach. Locality to co dostają utrzymujący kod: zmiana, błędy, wiedza i weryfikacja koncentrują się w jednym miejscu zamiast rozlewać się po wywołujących. Napraw raz, naprawione wszędzie.
Głęboki moduł = mały interfejs + dużo implementacji:
┌─────────────────────┐
│ Small Interface │ ← Mało metod, proste parametry
├─────────────────────┤
│ Deep Implementation │ ← Złożona logika ukryta
└─────────────────────┘
Płytki moduł = duży interfejs + mało implementacji (unikaj):
┌─────────────────────────────────┐
│ Large Interface │ ← Dużo metod, złożone parametry
├─────────────────────────────────┤
│ Thin Implementation │ ← Tylko przepuszcza dalej
└─────────────────────────────────┘
Głębokość jako stosunek linii implementacji do linii
interfejsu (Ousterhout) — nagradza rozdmuchiwanie
implementacji; tu głębokość = dźwignia. "Interface" to nie
słowo kluczowe interface z TypeScript ani same
publiczne metody klasy — za wąskie. "Boundary" nie jest tu
używane — przeciążone znaczeniem z DDD; mów "seam" albo
"interface".