2014-12-30 5 views
5

Possiedo un'app con circa 11 diverse istanze Singleton utilizzate nei numerosi metodi e classi dell'app; mi sta sfuggendo di mano e voglio sostituirli tutti con un'iniezione di dipendenze, come Typhoon. Tuttavia, non sono in grado di trovare alcun documento, campione o menzione su come sostituire i singleton con l'iniezione di dipendenza, incluso Typhoon. Ad esempio, utilizzo più istanze di Typhoon, sostituendo ogni singolo con un'istanza di Typhoon?L'iniezione di dipendenza come Typhoon sostituisce più singoli singleton?

risposta

9

Creatore di Typhoon qui. Sì, uno degli usi della dipendenza lo introduce per fornire i benefici dei singleton senza gli svantaggi. Ma non hai necessariamente bisogno di una libreria per applicare il modello di iniezione delle dipendenze e sostituire i tuoi singleton. Infatti aiuta a capire il modello, cercando in modalità di attuazione senza un quadro prima:

Hollywood Principio: non chiamarci, ti chiameremo

alto livello le classi, come i controller di visualizzazione, si riferiscono ai collaboratori per svolgere il proprio lavoro. Come hai detto hai circa 11 di questi. Ora ci sono due modi per accoppiare la classe per il collaboratore:

Cercare (call) il collaboratore:

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

E il modo di cui sopra funziona, ma non è un bene perché:

  • Se vuoi fornire un'implementazione alternativa, quindi devi andare e cambiare ogni classe che la usa.
  • Rende difficile la scrittura di unità pulite o test di integrazione. È necessario esaminare gli interni della classe (test della scatola di vetro) anziché concentrarsi sul contratto dell'interfaccia esterna (test della scatola nera).
  • Fornisce un accoppiamento troppo stretto, che porta a una scarsa coesione.

L'alternativa:

semplicemente passare il collaboratore, attraverso un metodo init o una proprietà.

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

Come è diverso da solo. . . passare argomenti?

Invece di eseguire il cablaggio di un collaboratore, lo si inoltra come argomento. Ma ora la prossima lezione è cablata! Così continui a farlo finché non hai una classe di assemblaggio di primo livello, che sa come costruire il tuo controller di visualizzazione (e altre classi) dai singoli pezzi. Se si esegue questa operazione:

  • Tutti i riferimenti a ogni singolo indicano un punto. Quindi la sostituzione di uno dei tuoi singleton con un'implementazione compatibile richiede solo una riga di modifica del codice. Allo stesso modo hai incapsulato la configurazione per questa classe.
  • La sua semplice scrittura di unità e test di integrazione per le vostre classi. In quest'ultimo caso, è possibile applicare una patch a un componente per un altro. Questo può superare due degli svantaggi dei test in stile integrazione. Il primo è che è difficile mettere il sistema nello stato richiesto per uno scenario di test, e il secondo è che possono avere effetti collaterali indesiderati. Nel frattempo, anche i test unitari semplici sono semplificati, dal momento che ora è facile vedere il contratto di dipendenza e passare in derisione o stub per questi.
  • Le classi documentano chiaramente le loro "cuciture" e quali sono i collaboratori significativi a cui verranno delegati per svolgere i loro compiti. Questo porta ad "alta coesione".

Ora Usando Typhoon:

Avrai uno conservato istanza di Typhoon per app normale. Terrà i tuoi singleton.

Se dopo aver studiato il materiale di cui sopra hai una domanda più specifica saremmo molto felici di aiutarti.

+1

HI Jasper ... questo è quello che stavo cercando ... fammi "cogitare" per un po 'e probabilmente tornerò da te. Grazie mille. Buon anno nuovo! : D A proposito, mi piace il tuo sito web (s) ... molto creativo! – SpokaneDude

+0

Sei il benvenuto e grazie per le gentili parole sul/sui sito/i :) (In realtà, se sei interessato, è un processo semplice: acquista alcuni bei modelli HTML5 online e poi aggiungi contenuti. Per AppsQuick.ly uno, l'illustrazione è stata gentilmente fatta da Loud & Clear a Melbourne, in Australia <--- Ho chiesto un'isola e alcune noci di cocco e abbastanza sicuro ... Ti auguro un 2015 felice e pacifico! –

+0

Perché usi 'self.serviceClient = serviceClient; 'in' initWitServiceClient' invece di '_serviceClient = serviceClient' come da [questa domanda SO] (https://stackoverflow.com/questions/17703221/why-i-should-access-the-instance-variable-directly- dall'interno di un'inizializzazione)? –

Problemi correlati