Przejdź do treści

DevStyle - Strona Główna
DI: Kilka refleksji po wprowadzonych zmianach

DI: Kilka refleksji po wprowadzonych zmianach

Maciej Aniserowicz

3 września 2015

Backend

Po dość znacznej przerwie powracamy jeszcze na chwilę do tematu Dependency Injection. Pamiętacie cykl i moment, do którego dotarliśmy? Zastosowaliśmy SRP by uprościć kod. Wprowadziliśmy jawne zależności między komponentami i ubraliśmy je w interfejsy. Spróbowaliśmy napisać własny kontener Dependency Injection, a potem zobaczyliśmy dlaczego lepiej użyć jednak czegoś gotowego. I stanęło na Autofac, kiedy to obiecałem “kilka finalnych refleksji”. Oto one.

Czy jest lepiej?

Tak, zdecydowanie można stwierdzić, że JEST lepiej. Po porównaniu kodu początkowego z kodem finalnym (tag demo5-start) aż dziw bierze, że tak proste zabiegi mogą mieć tak pozytywny efekt.

Zwiększyliśmy czytelność: zamiast jednej wielkiej klasy mamy teraz kilka mniejszych, mieszczących się na jednym ekranie. Takie komponenty łatwo jest przeczytać i zrozumieć. Szczerze mówiąc zwykle staram się pisać klasy w ten właśnie sposób: by całość mieściła się na jednym ekranie. Czy mam wtedy dużo klas? Tak! Czy to coś złego? Tu można dywagować, ale: u mnie się sprawdza.

Dzięki poprzedniemu zabiegowi: wprowadziliśmy testy. Znaleźliśmy nawet buga bez uruchamiania systemu i… poprawiliśmy go! O tym jak bardzo istotne są testy automatyczne dzisiaj rozpisywać się nie będę, ale: wiadomo jak jest :). Pokrycie testami pierwotnego kodu było średnio możliwe.

Wszystkie zastosowane zabiegi miały wpłynęły pozytywnie na najważniejszą cechę oprogramowania: stało się ono bardziej utrzymywalne! Do tego dążymy, o to dbamy, tym się jaramy i to nas kręci ;).

Ale…

Czy jest idealnie?

Nigdy nie jest idealnie :). Niestety, w aktualnej postaci nie jest nawet “wystarczająco dobrze“.

Spójrzmy na kawałek naszego UsersController:

public UsersController (
    IEmailValidator emailValidator,
    IActivationLinkGenerator activationLinkGenerator,
    IEmailService emailService
)
    {
        _emailValidator = emailValidator;
        _activationLinkGenerator = activationLinkGenerator;
        _emailService = emailService;
    }

https://github.com/maniserowicz/di-talk/blob/demo5-start/src/app/UsersController.cs

Co oczom naszym się ukazuje? Ano konstruktor. Z iloma zależnościami? Z trzema. Czy to dużo? Jak zwykle: “to zależy”. Trzy zależności zwykle “ujdą”, ale tutaj mamy do czynienia z zabawną sytuacją: kontroler potrzebuje do działania prawie wszystkich innych komponentów w systemie! Code-smell jak nic.

Wiecie dlaczego zostawiłem kod w takiej postaci i nie ciągnąłem refactoringu? Bo na dłuższą metę to nie ma sensu. Jeśli będziemy podążać tą drogą to i tak na końcu wylądujemy z brzydkim kontrolerem. “Kontrolerem-orchestratorem”. Jego jedyną odpowiedzialnością będzie przyjęcie X zależności i wywoływanie metod w odpowiedniej kolejności. “Przecież dokładnie do tego służy kontroler!” – mógłby ktoś zakrzyknąć. I z jednej strony: będzie miał rację. A z drugiej: kontrolery w MVC są bytem sztucznym i zbędnym (ale o tym innym razem).

W celu podniesienia jakości tego kodu jeszcze bardziej trzeba zmienić trochę podejście. “Wyewoluować” od standardowego MVC… trochę dalej. Wprowadzić do systemu pojęcie “komend”. I “zdarzeń”. Już wiadomo o czym mówię, o co chodzi, prawda? Naturalną konsekwencją mojej prezentacji o Dependency Injection było przygotowanie kolejnej, tym razem o CQRS. I tego tematu możecie wkrótce spodziewać się na blogu.

Zobacz również