2010-11-14 15 views

risposta

84

DI e strategia funzionano allo stesso modo, ma la strategia viene utilizzata per più dipendenze a grana fine e di breve durata.

Quando un oggetto è configurato con una strategia "fissa", ad esempio quando l'oggetto è costruito, la distinzione tra strategia e DI sfoca. Ma in uno scenario di DI è più insolito che le dipendenze degli oggetti cambino durante la loro vita, mentre questo non è raro con la Strategia.

Inoltre, è possibile passare le strategie come argomenti ai metodi, mentre il concetto correlato di argomento argomento dell'iniezione non è molto diffuso e viene utilizzato principalmente nel contesto dei soli test automatici.

La strategia si concentra sull'intenzione e incoraggia a creare un'interfaccia con diverse implementazioni che rispettano lo stesso contratto comportamentale. DI è più relativo alla semplice implementazione di alcuni comportamenti e alla sua fornitura.

Con DI è possibile scomporre il programma per altri motivi oltre al semplice scambio di parti dell'implementazione. Un'interfaccia utilizzata in DI con una sola implementazione è molto comune. Una "Strategia" con una sola implementazione concreta (mai) non è un problema reale ma probabilmente è più vicina a DI.

+0

Un'interfaccia utilizzata in DI con una sola implementazione è molto comune - quindi cosa è DI in questo caso particolare? –

+1

Questa citazione fondamentalmente spiega tutto: 'in uno scenario DI è più insolito che le dipendenze degli oggetti cambino durante la loro vita, mentre questo non è raro con Strategia –

+0

Strategia: Le classi sono progettate in modo che possano essere configurate con un algoritmo in fase di esecuzione.DI: Tali classi ottengono un algoritmo (un oggetto strategia) iniettato in fase di esecuzione. Dalla memoria dei modelli di progettazione GoF su http://w3sdesign.com. – GFranke

27

È possibile utilizzare DI come un modello di strategia, in modo da poter scambiare l'algoritmo necessario per ogni cliente, ma DI può andare oltre, in quanto è un modo per disaccoppiare semplicemente le parti di un'applicazione, che wouldn ' essere parte del modello strategico

Sarebbe azzardato dire che DI è solo un modello strategico ribattezzato che inizia a diluire ciò che il modello strategico è realmente per, IMO.

+2

Penso di capire il tuo senso, ma non riesco a inserirlo correttamente nelle parole ... Quindi il tuo DI è più di un modello di implementazione mentre la strategia è più di un modello di progettazione, e un modo per implementare la strategia è attraverso DI? –

+0

Sembra un buon modo per dirlo. DI è più di un semplice modello di strategia. Ho trovato la stessa confusione con AOP, dove la gente pensa che sia un modello di fabbrica. Penso che DI possa implementare il modello strategico, quindi la tua riformulazione sembrerebbe fantastica. :) –

+0

questo può aiutare troppo meravigliosamente formulato http://stackoverflow.com/a/4176811/22858 –

7

Le strategie sono cose di livello superiore che vengono utilizzate per modificare il modo in cui le cose vengono calcolate. Con l'iniezione di dipendenza, è possibile modificare non solo il modo in cui le cose vengono calcolate, ma anche modificare ciò che è lì.

Per me, diventa chiaro quando si utilizzano i test unitari. Per l'esecuzione del codice di produzione, hai tutti i dati nascosti (cioè privati ​​o protetti); mentre con i test unitari la maggior parte dei dati è pubblica, quindi posso esaminarla con gli Assert.


esempio della strategia:

public class Cosine { 
    private CalcStrategy strat; 

    // Constructor - strategy passed in as a type of DI 
    public Cosine(CalcStrategy s) { 
    strat = s; 
    } 
} 

public abstract class CalcStrategy { 
    public double goFigure(double angle); 
} 

public class RadianStrategy extends CalcStrategy { 
    public double goFigure(double angle) { 
    return (...); 
    } 
} 
public class DegreeStrategy extends CalcStrategy { 
    public double goFigure(double angle) { 
    return (...); 
    } 
} 

Si noti che non ci sono dati pubblici che è diverso tra le strategie. Né ci sono metodi diversi. Entrambe le strategie condividono tutte le stesse funzioni e firme.


Ora per l'iniezione di dipendenza:

public class Cosine { 
    private Calc strat; 

    // Constructor - Dependency Injection. 
    public Cosine(Calc s) { 
    strat = s; 
    } 
} 

public class Calc { 
    private int numPasses = 0; 
    private double total = 0; 
    private double intermediate = 0; 

    public double goFigure(double angle) { 
    return(...); 
} 

public class CalcTestDouble extends Calc { 
    // NOTICE THE PUBLIC DATA. 
    public int numPasses = 0; 
    public double total = 0; 
    public double intermediate = 0; 
    public double goFigure(double angle) { 
    return (...); 
    } 
} 

Usa:

public CosineTest { 

    @Test 
    public void testGoFigure() { 
    // Setup 
    CalcTestDouble calc = new CalcTestDouble(); 
    Cosine instance = new Cosine(calc); 

    // Exercise 
    double actualAnswer = instance.goFigure(0.0); 

    // Verify 
    double tolerance = ...; 
    double expectedAnswer = ...; 
    assertEquals("GoFigure didn't work!", expectedAnswer, 
     actualAnswer, tolerance); 

    int expectedNumPasses = ...; 
    assertEquals("GoFigure had wrong number passes!", 
     expectedNumPasses, calc.numPasses); 

    double expectedIntermediate = ...; 
    assertEquals("GoFigure had wrong intermediate values!", 
     expectedIntermediate, calc.intermediate, tolerance); 
    } 
} 

Avviso ultimi 2 assegni. Hanno usato i dati pubblici nel test double che è stato iniettato nella classe sotto test. Non potevo farlo con il codice di produzione a causa del principio di nascondimento dei dati . Non volevo avere un codice di test per scopi speciali inserito nel codice di produzione. I dati pubblici dovevano essere in una classe diversa.

Il test double è stato iniettato. Questo è diverso da una semplice strategia poiché ha interessato i dati e non solo le funzioni.

11

Amico, l'iniezione di dipendenza è un modello più generale, e si tratta di dipendenza da astrazioni non concrezioni ed è una parte di ogni modello, ma modello di strategia è una soluzione al più specifica problema

questa è la definizione da wikipedia :

dI:

Dipendenza iniezione (dI) in programmazione orientata agli oggetti calcolatore è un modello di progettazione con un nucleo principio SEP comportamento arating dalla risoluzione delle dipendenze . In altre parole: una tecnica per il disaccoppiamento altamente componenti software dipendenti.

strategia Modello:

In programmazione, la strategia modello (noto anche come il modello politica ) è un particolare software disegno del modello, per cui algoritmi possono essere selezionati in fase di esecuzione.

Il modello di strategia è destinato a fornire un mezzo per definire una famiglia di algoritmi, incapsulare ognuno come oggetto , e renderli intercambiabili. Il modello di strategia consente agli algoritmi di variare in modo indipendente dai client che li utilizzano.

33

La differenza è ciò che stanno cercando di ottenere. Il modello di strategia viene utilizzato in situazioni in cui si sa che si desidera sostituire le implementazioni. Ad esempio, potresti voler formattare i dati in diversi modi: potresti utilizzare il modello di strategia per scambiare un formattatore XML o un formattatore CSV, ecc.

Iniezione di dipendenza è diverso in quanto l'utente non sta provando a modificare il comportamento di runtime. Seguendo l'esempio sopra, potremmo creare un programma di esportazione XML che utilizza un formattatore XML. Invece di strutturare il codice in questo modo:

public class DataExporter() { 
    XMLFormatter formatter = new XMLFormatter(); 
} 

si 'inietta' il formattatore nel costruttore:

public class DataExporter { 
    IFormatter formatter = null; 

    public DataExporter(IDataFormatter dataFormatter) { 
    this.formatter = dataFormatter; 
    } 
} 

DataExporter exporter = new DataExporter(new XMLFormatter()); 

Ci sono alcune giustificazioni per Dependency Injection, ma quello principale è per il test. Potresti avere un caso in cui hai un motore di persistenza di qualche tipo (come un database). Tuttavia, può essere un problema usare un vero database quando si eseguono ripetutamente dei test. Quindi, per i tuoi casi di test, dovresti iniettare un database fittizio, in modo da non dover sostenere quel sovraccarico.

Utilizzando questo esempio, si può vedere la differenza: abbiamo sempre pensa di utilizzare una strategia di storage dei dati, ed è quello che passiamo (il vero DB di istanza).Tuttavia, nello sviluppo e nel test, vogliamo utilizzare diverse dipendenze, quindi iniettiamo concrezioni diverse.

3

L'iniezione di dipendenza è un raffinamento del modello di strategia che illustrerò brevemente. Spesso è necessario scegliere tra diversi moduli alternativi in ​​fase di esecuzione. Questi moduli implementano un'interfaccia comune in modo che possano essere usati in modo intercambiabile. Lo scopo del modello strategico è rimuovere l'onere di decidere quale dei moduli utilizzare (cioè quale "strategia concreta" o dipendenza) incapsulando il processo decisionale in un oggetto separato che chiamerò oggetto della strategia.

L'iniezione di dipendenza perfeziona lo schema della strategia non solo decidendo quale strategia concreta utilizzare ma creando un'istanza della strategia concreta e "inserendola" nel modulo di chiamata. Questo è utile anche se c'è solo una singola dipendenza come la conoscenza di come gestire (inizializzare ecc.) L'istanza della strategia concreta può anche essere nascosta all'interno dell'oggetto della strategia.

2

In realtà, l'iniezione di dipendenza sembra molto simile al modello Bridge. Per me (e secondo la definizione), il pattern Bridge è adatto a diverse versioni dell'implementazione, mentre il modello di strategia è per la logica completamente diversa. Ma il codice di esempio sembra che stia usando DI. Quindi forse DI è solo una tecnica o un'implementazione?

1

La strategia è un'arena per utilizzare le tue abilità di iniezione di dipendenza. modi reali per attuare l'iniezione di dipendenza sono i seguenti: -

  1. Eventi
  2. I file di configurazione di carta dell'unità/struttura (oa livello di programmazione), ecc
  3. Metodi di estensione modello
  4. Abstract Factory
  5. Inversion del modello di controllo (utilizzato sia dalla strategia che dalla fabbrica astratta)

C'è una cosa sebbene ciò faccia in modo che la strategia si distingua. Come sapete in Unity all'avvio dell'applicazione, tutte le dipendenze sono impostate e non possiamo modificarle ulteriormente. Ma la strategia supporta la modifica della dipendenza di runtime. Ma dobbiamo gestire/iniettare la dipendenza, non la responsabilità della strategia!

In realtà la strategia non parla dell'iniezione di dipendenza. Se necessario, può essere fatto attraverso Abstract Factory all'interno di un modello di strategia. La strategia parla solo della creazione di una famiglia di classi con interfaccia e 'giocando' con essa. Durante il gioco, se troviamo che le classi si trovano in un livello diverso, dobbiamo iniettarle noi stessi, ma non il lavoro di Strategia.

Problemi correlati