2014-12-30 4 views
5

Mam aplikację, która ma około 11 różnych instancji Singleton używanych w metodach i klasach wielu aplikacji; to wymyka się spod kontroli i chcę zastąpić wszystkie z nich zastrzykiem zależności, jak na przykład Typhoon. Jednak nie jestem w stanie znaleźć żadnego dokumentu, próbki ani wzmianki o tym, jak zastąpić singletony zastrzykiem zależności, w tym Typhoon. Na przykład, czy używam wielu instancji Typhoon, zastępując każdy singleton instancją Typhoon?Czy wstrzyknięcie zależne od narkotyków może być podobne do Typhoon zamiast wielu singletonów?

Odpowiedz

9

Twórca tajfunu tutaj. Tak, jeden z zastosowań zależności wstrzykuje go, aby zapewnić korzyści z singletonów bez wad. Ale niekoniecznie potrzebujesz biblioteki, aby zastosować wzór zastrzyku zależności i zastąpić pojedyncze. W rzeczywistości to pomaga zrozumieć, patrząc na wzór, jak zaimplementować go bez pierwszy ramy:

Hollywood Zasada: Nie zadzwonić do nas, będziemy nazywać Cię

wysokim poziomie klasy, takie jak kontrolery widoku, przekazują współpracownikom, aby wykonali swoją pracę. Jak już wspomniałeś, masz około 11 z nich. Teraz jest na dwa sposoby para klasa do współpracownika:

Poszukiwania (call) współpracownika:

initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle 
{ 
    self = [super initWithNibName:nibname bundle:bundle]; 
    if (self) { 
     _serviceClient = [MyServiceClient sharedInstance]; 
    } 
} 

i działa powyższy sposób, ale jej nie jest dobre, ponieważ:

  • Jeśli chcesz zapewnić alternatywną implementację, musisz przejść i zmienić każdą klasę, która go używa.
  • Utrudnia pisanie czystych jednostek lub testy integracyjne. Musisz zajrzeć do wnętrza klasy (testowanie szklanych pudełek) zamiast skupić się na zewnętrznej umowie interfejsu (testowanie czarnej skrzynki).
  • Zapewnia zbyt mocne połączenie, które prowadzi do słabej spójności.

Alternatywnie:

Proszę przejść wspomagającej, za pomocą metody inicjalizującego lub nieruchomości.

initWitServiceClient:(id<ServiceClient>)serviceClient 
{ 
    self = [super initWithNibName:@"MyNib" bundle:[NSBundle mainBundle]; 
    if (self) { 
     _serviceClient = serviceClient; 
    } 
} 

Jak to się różni? . . przekazywanie argumentów?

Zamiast ciężkiego okablowania współpracownika przekazujesz go jako argument. Ale teraz kolejna klasa jest trudna! Tak więc robisz to dopóki nie będziesz mieć klasy montażowej najwyższego poziomu, która wie, jak zbudować kontroler widoku (i inne klasy) z poszczególnych elementów. Jeśli to zrobisz:

  • Wszystkie odniesienia do każdego singleton wskazuje na jedno miejsce. Zastąpienie jednego z twoich singletonów zgodną implementacją wymaga zmiany tylko jednego wiersza kodu. Podobnie hermetyzowałeś konfigurację dla tej klasy.
  • Umożliwia łatwe pisanie testów jednostkowych i integracyjnych dla zajęć. W tym drugim przypadku możesz załatać jeden komponent dla drugiego. Może to przezwyciężyć dwie wady testów stylu integracji. Pierwszym jest to, że trudno jest umieścić system w wymaganym stanie dla scenariusza testowego, a po drugie, że mogą mieć niepożądane skutki uboczne. W międzyczasie czysto jednostkowe testowanie jest również uproszczone, ponieważ teraz łatwo jest zobaczyć umowę o uzależnienie i przekazać ją w postaci mocks lub stubów.
  • Klasy wyraźnie dokumentują ich "szwy" i znaczących współpracowników, do których będą delegować w celu wykonywania swoich zadań. Prowadzi to do "wysokiej spójności".

Teraz Korzystanie Typhoon:

Będziesz mieć jeden zachowany egzemplarz Typhoon na normalnej aplikacji. Będzie trzymać wasze singletony.

Jeśli po przestudiowaniu powyższego materiału masz bardziej szczegółowe pytanie, chętnie pomożemy.

+1

HI Jasper ... to jest to, czego szukałem ... pozwól mi "trochę się z tym pogodzić" i pewnie wrócę do ciebie. Dziękuję Ci bardzo. Mieć bezpieczny Nowy Rok! : D Nawiasem mówiąc, podoba mi się twoja strona (i) ... bardzo kreatywna! – SpokaneDude

+0

Nie ma za co, dziękuję za miłe słowa dotyczące strony internetowej :) (Właściwie, jeśli jesteś zainteresowany, to jest to prosty proces: kup kilka fajnych szablonów HTML5 online, a następnie dodaj zawartość. Po pierwsze, ilustracja została wykonana uprzejmie przez Loud & Clear w Melbourne w Australii <--- Prosiłem o wyspę i trochę kokosów i na pewno ... Życzę wam także szczęśliwego i spokojnego 2015 roku –

+0

Dlaczego używacie 'self.serviceClient = serviceClient; 'in' initWitServiceClient' zamiast '_serviceClient = serviceClient' zgodnie z [tym pytaniem SO] (https://stackoverflow.com/questions/17703221/whyi-i-direct-instown-instance-variable-directly- od-in-an-initialization)? –

Powiązane problemy