W ubiegłym roku stworzyłem nowy system przy użyciu Dependency Injection i kontenera IOC. To nauczyło mnie wiele o DI!
Jednak nawet po zapoznaniu się z pojęciami i właściwymi wzorami uważam za wyzwanie rozdzielić kod i wprowadzić kontener IOC do starszej aplikacji. Aplikacja jest na tyle duża, że prawdziwa implementacja byłaby przytłaczająca. Nawet jeśli wartość została zrozumiana i czas został przyznany. Kto ma czas na coś takiego?
Celem jest oczywiście wprowadzenie testów jednostkowych do logiki biznesowej!
Logika biznesowa powiązana z zabezpieczającymi wywołania wywołaniami bazy danych.
Przeczytałem artykuły i rozumiem niebezpieczeństwa wstrzyknięcia uzależnienia od biednego człowieka, jak opisano w tym artykule Los Techies . Rozumiem, że tak naprawdę niczego nie oddziela.
Rozumiem, że może to wymagać dużego refaktoryzacji całego systemu, ponieważ implementacje wymagają nowych zależności. Nie rozważałbym użycia go w nowym projekcie o dowolnej wielkości.
Pytanie: Czy można używać DI Poor Man do wprowadzenia testowalności do starszej aplikacji i zacząć toczyć piłkę?
Ponadto, czy stosowanie DI biednego człowieka jako oddolnego podejścia do prawdziwego wstrzykiwania zależności jest cennym sposobem edukowania na temat potrzeby i korzyści wynikających z tej zasady?
Czy można refaktoryzować metodę, która ma zależność od wywołań bazy danych i streszczenie, która wywołuje interfejs? Po prostu posiadanie tej abstrakcji sprawiłoby, że ta metoda byłaby testowalna, ponieważ próbna implementacja mogłaby zostać przekazana przez przeciążenie konstruktora.
W przyszłości, gdy wysiłek zyska zwolenników, projekt może zostać zaktualizowany w celu wdrożenia kontenera MKOl, a konstruktorzy będą tam, którzy przyjmą abstrakcje.
I consider it a challenge to decouple code and introduce an IOC container into a legacy application
oczywiście że tak. To się nazywa dług techniczny. Dlatego przed każdą poważną modernizacją lepiej jest stosować małe i ciągłe refaktory. Zmniejszenie głównych wad projektowych i przejście do IoC byłoby mniej trudne.Odpowiedzi:
Krytyka dotycząca iniekcji Biednego Człowieka w NerdDinner ma mniej wspólnego z tym, czy używasz kontenera DI, czy z prawidłowym konfigurowaniem klas.
W artykule stwierdzają to
jest niepoprawny, ponieważ chociaż pierwszy konstruktor zapewnia wygodny mechanizm rezerwowy do konstruowania klasy, tworzy również ściśle związaną z nim zależność
DinnerRepository
.Prawidłowym lekarstwem nie jest oczywiście, jak sugeruje Los Techies, dodanie kontenera DI, ale usunięcie szkodliwego konstruktora.
Pozostała klasa ma teraz poprawnie odwrócone zależności. Możesz teraz wstrzykiwać te zależności w dowolny sposób.
źródło
XService
parametr przekazuje parametr doXRepository
i zwraca to, co otrzymuje, nie jest zbyt przydatne dla nikogo i nie daje zbyt wiele możliwości rozszerzenia. Napisz testy jednostkowe, aby przetestować sensowne zachowanie i upewnić się, że komponenty nie są tak wąskie, że w rzeczywistości przenosisz całą logikę do katalogu głównego kompozycji.Zakładasz tutaj fałszywe przypuszczenie, co to jest „DI biedaka”.
Stworzenie klasy, która ma konstruktor „skrótu”, który wciąż tworzy sprzężenie, nie jest DI dla biednych ludzi.
Nieużywanie kontenera i ręczne tworzenie wszystkich zastrzyków i mapowań to DI biedaka.
Termin „DI biedaka” wydaje się złym posunięciem. Z tego powodu zachęca się dziś do określenia „czysta DI”, ponieważ brzmi to bardziej pozytywnie i właściwie dokładniej opisuje ten proces.
Nie tylko absolutnie w porządku jest użycie DI biednego człowieka / czystego człowieka do wprowadzenia DI do istniejącej aplikacji, ale jest to również prawidłowy sposób używania DI dla wielu nowych aplikacji. I jak mówisz, każdy powinien używać czystego DI w co najmniej jednym projekcie, aby naprawdę zrozumieć, jak działa DI, zanim przejmie odpowiedzialność za „magię” pojemnika IoC.
źródło
Zmiany paragidów w starszych zespołach / bazach kodu są niezwykle ryzykowne:
Użycie DI Framework jako młota do zniszczenia wszystkich gwoździ sprawi, że starszy kod będzie gorszy niż lepszy we wszystkich przypadkach. Jest to również bardzo ryzykowne osobiście.
Nawet w najbardziej ograniczonych przypadkach, takich jak tylko tak, aby można go było użyć w przypadkach testowych, sprawi, że te przypadki testowe będą „niestandardowe” i „obce”, które w najlepszym wypadku zostaną po prostu zaznaczone,
@Ignore
gdy się zepsują lub gorzej, będą ciągle narzekać programiści o największej sile rażenia w zarządzaniu i przepisywani „poprawnie” z całym tym „marnowaniem czasu na testy jednostkowe” obwinianym wyłącznie za ciebie.Dependency Injection to rozwiązanie szukające problemu.
Wstrzyknięcie zależności jest przydatne tylko w małych dawkach dla bardzo wąskiego zakresu rzeczy:
Rzeczy, które bardzo się zmieniają lub mają wiele alternatywnych implementacji, które są związane statycznie.
Systemy wtyczek, które mają konfigurowalne wtyczki, które można zdefiniować w kodzie konfiguracji w twoim frameworku i które są automatycznie wykrywane podczas uruchamiania i dynamicznie ładowane / ładowane ponownie podczas działania programu.
źródło