Załóżmy, że mamy 1001 klientów, którzy konstruują swoje zależności bezpośrednio, zamiast akceptować zastrzyki. Według naszego szefa refaktoryzacja 1001 nie jest opcją. W rzeczywistości nie mamy nawet dostępu do ich źródła, tylko do plików klas.
Powinniśmy „zmodernizować” system, przez który przechodzi 1001 klientów. Możemy refaktoryzować to, co lubimy. Zależności są częścią tego systemu. I niektóre z tych zależności, które mamy zmienić, aby mieć nową implementację.
Chcielibyśmy mieć możliwość konfigurowania różnych implementacji zależności, aby zaspokoić tę liczbę klientów. Niestety DI nie wydaje się opcją, ponieważ klienci nie akceptują zastrzyków z konstruktorami lub ustawiaczami.
Opcje:
1) Refaktoryzuj implementację usługi, z której korzystają klienci, aby spełniała ona potrzeby klientów. Bang, skończyliśmy. Nie elastyczny. Niezbyt skomplikowane.
2) Refaktoryzuj implementację, aby delegowała pracę do kolejnej zależności, którą nabywa za pośrednictwem fabryki. Teraz możemy kontrolować, z której implementacji korzystają wszyscy, poprzez refaktoryzację fabryki.
3) Przeprowadź refaktoryzację implementacji, aby delegowała pracę do kolejnej zależności, którą uzyskuje za pośrednictwem lokalizatora usług. Teraz możemy kontrolować, z której implementacji korzystają wszyscy, konfigurując lokalizator usług, który może być po prostu hashmap
ciągiem znaków do obiektów z niewielkim rzutowaniem.
4) Coś, o czym nawet jeszcze nie pomyślałem.
Cel:
Zminimalizuj szkody projektowe spowodowane przeciąganiem starego, źle zaprojektowanego kodu klienta w przyszłość bez zwiększania bezsensownej złożoności.
Klienci nie powinni wiedzieć ani kontrolować wdrażania swoich zależności, ale nalegają na ich budowanie new
. Nie możemy kontrolować, new
ale kontrolujemy klasę, którą budują.
Moje pytanie:
Czego nie wziąłem pod uwagę?
czy naprawdę potrzebujesz możliwości konfiguracji między różnymi implementacjami? W jakim celu?
Zwinność. Wiele niewiadomych. Kierownictwo chce możliwości zmian. Tracą jedynie zależność od świata zewnętrznego. Także testowanie.
czy potrzebujesz mechaniki czasu wykonywania, czy po prostu mechaniki kompilacji czasu, aby przełączać się między różnymi implementacjami? Dlaczego?
Prawdopodobnie wystarcza mechanika czasu kompilacji. Z wyjątkiem testów.
jakiej szczegółowości potrzebujesz, aby przełączać się między implementacjami? Wszystko na raz? Na moduł (każdy zawierający grupę klas)? Na zajęcia?
Ze 1001 tylko jeden jest uruchamiany w systemie w dowolnym momencie. Zmiana, z której korzystają wszyscy klienci naraz, jest prawdopodobnie w porządku. Prawdopodobnie ważna jest jednak indywidualna kontrola zależności.
kto musi kontrolować przełącznik? Tylko Twój zespół programistów? Administrator? Każdy klient na własną rękę? A może deweloperzy konserwacji kodu klienta? Jak łatwa / niezawodna / niezawodna musi być mechanika?
Dev do testowania. Administrator wraz ze zmianami zależności zewnętrznych urządzeń. Musi być łatwy do przetestowania i skonfigurowania.
Naszym celem jest pokazanie, że system można szybko przerobić i zmodernizować.
rzeczywisty przypadek użycia przełącznika implementacji?
Po pierwsze, niektóre dane będą dostarczane przez oprogramowanie, dopóki rozwiązanie sprzętowe nie będzie gotowe.