DI: Kilka refleksji po wprowadzonych zmianach

11

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.

Share.

About Author

Programista, trener, prelegent, pasjonat, blogger. Autor podcasta programistycznego: DevTalk.pl. Jeden z liderów Białostockiej Grupy .NET i współorganizator konferencji Programistok. Od 2008 Microsoft MVP w kategorii .NET. Więcej informacji znajdziesz na stronie O autorze. Napisz do mnie ze strony Kontakt. Dodatkowo: Twitter, Facebook, YouTube.

11 Comments

  1. Pingback: dotnetomaniak.pl

  2. Maciej Nowicki on

    Cześć Maciej!

    Po pierwsze miło zobaczyć nowy, techniczny wpis na blogu po wakacyjnym odwyku :)! Gratuluje również nowego Layoutu (widziałem już pare dni temu, ale nie było gdzie zostawić komentarza) – krok w bardzo dobrą stronę, bo stary mimo, że dawał poczucie profesjonalizmu (coś a’la ‘nie mam czasu na fajerwerki, zajmuję się poważnymi rzeczami’ ;) ) to byl już trochę zbyt przestarzały.

    Co prawda zajmuję się głównie desktopowym .NETem, ale bardzo zaciekawiło mnie Twoje spostrzeżenie odnośnie wirtualności kontrolerów, idealnie wpasowałeś się w moje ostatnie rozważania na temat zastosowania kontrolerów wraz ze wzorcem MVVM. Jakiś czas temu, w ramach prób przekonania się do aplikacji webowych testowałem zastosowanie VM w MVC (dla zainteresowanych: http://www.edandersen.com/2013/05/30/asp-net-mvc-basics-part-2-viewmodel-to-model-mapping-and-editing/) i pozytywne wrażenia z tego eksperymentu zachęciły mnie to do eksperymentownia z architekturą aplikacji. Zasiałeś ziarno niepewnosci i muszę się dobrze zastanowić, czy zmierzam w dobrym kierunku.

    Pozdrawiam,
    Maciek

  3. Aż sie prosi o fasadę do prawdziwej aplikacji. Kontroler powinien zawierać cały shit związany z HTTP czyli odp rediredty, status codey itp, to ze ma wziąć/wziasc z tej czy innej klasy to już logika aplikacji.

    Ja bym widział w tej fasadzie use caseowe metody w stylu generate link , send e-mail. Fasada powinna jednoznacznie mowić co róbi aplikacja. Kontroler zaś tylko tłumaczy generyczna aplikacje na świat HTTP

    • @rek,
      No nie wiem czy w tym przypadku widziałbym w kontrolerze coś takiego jak “generate link”. Tutaj use-case to właśnie “register user”, a akurat częścią jest generowanie linku. Nie wiem czy śledziłeś/pamiętasz cały cykl, ale wrzucenie do kontrolera bardziej granularnych metod w tym przypadku moim zdaniem mija się z celem.

      A że w większości aplikacji logika siedzi w kontrolerach, a nie powinna, to się zgadzam :).

    • JA,
      W przyszłości, to jedyna sensowna rzecz którą jestem w stanie napisać :). Raczej nie wcześniej niż listopad/grudzień, może nawet styczeń.

  4. Mocno się zdziwiłem jak wpadłem w nowy layout. Myślałem, że znajduje się na jakimś blogu kulinarnym :).
    Wracając do root tematu, jak pozbyć się nadmiarowości w konstruktorze ? Jestem amatorem i często mój kontroler puchnie z uwagi na rozszerzająca się funkcjonalność, co skutkuje pojawianiem się coraz większej ilości serwisów w konstruktorze.

    • PATRYK,
      Co do layout: jest tak jak miało być, blog NIE MA wyglądać jak typowy blog technologiczny – mission accomplished :).
      A zbyt dużo zależności w konstruktorze (tzn więcej niż 3-4 max) oznacza, że źle zamodelowałeś problem. Brakuje jakiegoś klocka w tej obiektowej układance. Część zależności trzeba zagregować w nowej klasie.

Newsletter devstyle!
Dołącz do 2000 programistów!
  Zero spamu. Tylko ciekawe treści.
Dzięki za zaufanie!
Do przeczytania wkrótce!
Niech DEV będzie z Tobą!