Co o tym podejściu sądzicie:
https://medium.com/clean-code-development/stratified-design-over-layered-design-125727c7e15
Trochę charakterystyczne dla osób, które preferują bottom-up
Idąc w kierunku stratified design poszczególnym komponentom wystarczy przekazać dane zamiast referencji na konkretny mutowalny obiekt w którego sercu często są ukryte mutacje i kontakt ze światem (nic dobrego).
Dla mnie tutaj ciekawe jest dostrzeżenie dwóch faktów, które wynikają, gdy pominie się wstrzykiwanie obiektów:
-
Komponenty z logiką wtedy nie tylko nie muszą o sobie wzajemnie nic wiedzieć (co upraszcza pisanie szybkich testów, bo nie trzeba nic mockować), ale również nie ukrywają komunikacji wewnątrz siebie, komponenty wystawia metody do zarządzania sobą. Te metody interesują głównie wartości, a zatem częściej pojawia się opcja do skorzystania z niemodyfikowalnych danych.
-
Komponenty nie są od siebie zależne, a więc są prostsze (pomyśl o tym jak o możliwym mutowaniu jakie ma miejsce gdy przekazujesz mutowalny obiekt do publicznej metody). Unikamy w ten sposób osadzenia interakcji wewnątrz komponentu, zamiast tego wypychamy tą interakcję do góry, na zewnątrz, a co za tym idzie w komponencie zostaje sama to logika.
Czyli:
- mamy prostszy sposób na zapisanie testu (mniej rytuałów i więcej konkretów)
- docelowy komponent zawiera w sobie tylko logikę i pisząc testy testujemy tylko logikę (o to chodzi), a nie interakcję wielu komponentów
Myśle, że to jest właśnie dobra odpowiedź na bolączki jakie poruszane są przy testach typu: nie piszą mniejszych testów (bo i po co skoro te testy przysypać mogą), albo nie piszą ich na mniejszą skalę (bo i po co skoro szerszy test również to samo pokryje). Moim zdaniem to jest życzeniowe myślenie. Szerszy test sprawdzi interakcje między komponentami, łatwo zrobi pokrycie wykonania kodu bliske 80-100%, ale co oznacza ten % Czy % wykonanego kodu przekłada się na taki sam %pokrycia logki? No nie jest tak. Możesz uruchomić raz metodę z jednym przypadkiem, czy to oznacza, że jest wszystko jest wtedy poprawne? No własnie nie bardzo, musisz sprawdzić przypadki brzegowe inaczej zgadujesz, że działa. Dziwi mnie za każdym razem jak ktoś często w dyskusjach zasłania się mocą statycznego typowania, to oczywiście rzutuje na poprawność, ale jest to poprawność w typach, w przekazywanu wartości, a typy to wciąż nie jest logika więc to rozumowanie zawsze będzie dla mnie niepojęte.
UWAGA: Po przez ten tekst nie nie zmierzam nikomu psuć dnia (chociaż byłoby miło wzbudzić w kimś ziarno wątpliwości). Po prostu dziwi mnie to, że tego sposobu nigdy w firmach nie widziałem, mimo, że słyszałem o oddolnym podejściu, ale nigdy nie czułem jaki może mieć ono mieć wpływ na pisanie lżejszych testów i prostszej logiki.
Byłoby super podyskutować o problemach, czy możecie uargumentować logicznie swój wybór dlaczego projekty w firmach nie idą w tą stronę?
Zwracam uwagę, że to podejscie nie ma związku z FP (chociaż hasla takie jak unikanie interaktywność / efekty uboczne / niemodyfikowalne wartości) sugerują jakby mieć powinno związek. FP jest pomocne, ale to podejście również można zastosować w obiektowych, czy nawet nieobiektowych językach takich jak C.
Odnośnie problemów jakie sam widzę to fakt, że tutaj jak widzimy, interakcja jest wypychana do góry, a zatem żaden pomniejszy komponent nie chcę przejąć za nią odpowiedzialności. Myślę, że to podejście ciężej jest spiąć z frameworkiem (który interakcje osadza głęboko w strukturze naszego kodu więc często nie mamy na to żadnego wpływu) i być to jest powód dla którego to podejscie się nie przyjeło.