2015-07-16 24 views
6

W aplikacjach na system Android używam Otto jako magistrali zdarzeń i Dagger dla wtrysku zależności.Zalety wstrzykiwania magistrali zdarzeń Otto zamiast używania statycznego singletonu

W podręczniku użytkownika Otto oraz w wielu postach na blogu zaleca się użycie wtrysku, aby uzyskać singleton. Robiłem to od jakiegoś czasu, ale ostatnio jestem coraz bardziej wątpliwy, czy wstrzyknięcie autobusu ma jakiekolwiek zalety w porównaniu z prostym statycznym singletonem.

Z wtryskiem muszę wstrzyknąć każdy niestandardowy widok lub ViewHolder, że chcę móc publikować zdarzenia interfejsu użytkownika na magistrali. Zwłaszcza ze sztyletem wydaje się nieco niezdarne wstrzykiwanie każdej klasy, w której potrzebuję autobusu. Oczywiście, mógłbym przekazać magistralę za pomocą konstruktora lub metody ustawiającej, ale to może być trochę niezgrabne, jeśli myślisz o adapterze z wieloma różnymi typami widoków, na przykład.

I nie widzę żadnych korzyści w wstrzykiwaniu autobusu. W przypadku Otto wprowadzana jest konkretna implementacja (przykład Bus), która nigdy się nie zmieni. Zawijanie Otto do de-łączenia nie ma sensu, jeśli myślisz, ze względu na sposób działania subskrypcji.

Czy ktoś widzi jakieś zalety wstrzyknięcia Otto, którego nie widzę?

+0

Spójrz na http://stackoverflow.com/questions/2662842/dependency-injection-singleton-design-pattern – pjanecze

+0

dziękuję, to bardzo pouczające. –

Odpowiedz

1

Moim zdaniem zdecydowanie powinieneś zawinąć magistral zdarzeń w swojej własnej klasie i użyć technik wtrysku zależnego, aby przekazać go klientom.

enter image description here

Istnieje kilka zalet tego podejścia nad prostu uzyskiwania odniesienie poprzez wywołanie metody statycznej getInstance():

  • Twoje zależności stają się wyraźne. Po uzyskaniu odwołań do obiektów za pośrednictwem wywołań statycznych zależności są ukryte w implementacji klientów, co powoduje, że kod jest kruchy i trudniejszy do zrozumienia.
  • Łatwiej będzie przełączyć się na inną implementację szyny zdarzeń, jeśli zajdzie taka potrzeba.
  • Inedowane zależności są łatwiejsze do kpienia w testach
  • Fakt, że techniki wprowadzania zastrzyków wprowadzają pewien stopień walki, jest w rzeczywistości dobrą rzeczą - jeśli walczysz, często oznacza to, że robisz coś źle. W twoim przypadku podejrzewam, że nadużywasz autobusu zdarzeń.

Mówię, że możliwe jest, że nadużywasz magistrali zdarzeń, ponieważ tak naprawdę nie widzę powodu, dla którego powinieneś mieć odniesienie do niego w podklasach View. Przypuszczam, że publikujesz powiadomienia o interakcjach użytkowników z magistralą zdarzeń, a następnie subskrybujesz Activity lub Fragment na magistralę zdarzeń, aby przechwycić te zdarzenia. Magistrala zdarzeń jest w tym przypadku niewłaściwym narzędziem (mimo że działa świetnie).

Powodem, dla którego magistrala zdarzeń jest niewłaściwym narzędziem w tym przypadku, jest to, że Fragments i Activity mogą mieć bezpośredni dostęp do zawartych obiektów View. Możesz uzyskać odniesienia do tych Views i zarejestrować Fragments i Activities jako słuchaczy. Nie ma potrzeby rozłączania niczego tutaj.

Wręcz przeciwnie: pomyśl o sprawie, w której zmierzasz i naprawisz swoją Views w taki sposób, że nic nie będzie już wysyłane do magistrali zdarzeń (powiedzmy, że wymagania biznesowe zostały zmienione).Od Views powiadomienia są tylko luźno związane z zawierającymi Fragment lub Activity przez magistralę zdarzeń, jest bardzo prawdopodobne, że zapomnisz usunąć logikę obsługi zdarzeń z Fragment i Activity, pozostawiając "martwy kod". To bardzo szybko się brudzi.

Im lepsza praktyka byłoby użyć Obserwatora wzorca projektowego i niech Views zawiadomić Activities i Fragments bezpośrednio, a jedynie podczas pracy obejmuje drugi składnik (których nie można łatwo dojechać z Fragment i Activity, np innego Fragment lub Activity) będzie komponenty te wysyłają zdarzenia do magistrali zdarzeń. Jeśli zastosujesz to podejście, będziesz musiał odwoływać się do magistrali zdarzeń tylko w "komponentach najwyższego poziomu" i nie będzie to miało wpływu na walkę.

P.S. Niedawno opublikowałem numer blog post which introduces some best practices for dependency injection in Android.