Costruttore per istanza in attesa di fabbrica utilizzata solo nei prodotti

3

Ho una fabbrica che crea prodotti. Per fare questo ho bisogno di un'istanza di qualche altra classe, che non ha nulla a che fare con la fabbrica attuale. Tuttavia, tutti i prodotti dovrebbero ovviamente utilizzare la stessa istanza di esso, quindi ho fornito quell'istanza alla factory che poi la passa a ogni istanza di Product :

public class MyFactory
{
    Product CreateProduct(MyClass dependency) 
    {
        return new Product(dependency);
    }
}

public class Product
{
    internal Product(MyClass dependency) { ... }
    public void DoSomething() { /* use the dependency */ }
}

Tuttavia mi sembra strano fornire qualcosa alla mia fabbrica che non è necessario ma passa semplicemente ai suoi prodotti.

L'altra alternativa che mi viene in mente è di fornire la dipendenza laddove è effettivamente necessaria, questo è il DoSomething -method in Product . Tuttavia, ciò consentirebbe agli utenti della mia API di fornire diverse istanze di MyClass a diversi prodotti come mostrato qui:

public class Product
{
    public void DoSomething(MyClass dependency) { /* use the dependency */ }
}

...
var dependency1 = new MyClass();
var dependency2 = new MyClass();
myProduct.DoSomething(dependency1);
anotherProduct.DoSomething(dependency2);

La domanda quindi è: va bene fornire una dipendenza alla mia fabbrica che in realtà è una dipendenza per l'attuale Product ?

    
posta HimBromBeere 24.05.2017 - 09:18
fonte

3 risposte

4

L'ho fatto in uno scenario simile: i "prodotti" comunicano tramite la porta seriale, quindi la "fabbrica" doveva dare la stessa istanza di quella porta seriale (evitare problemi di multi-threading!) ai suoi prodotti.

Secondo me, la fabbrica dovrebbe "iniettare" tutte le dipendenze richieste dai suoi prodotti, restituendo così i "prodotti" completamente funzionali.

    
risposta data 24.05.2017 - 10:30
fonte
2

Suppongo che lo scenario che stai immaginando sia questo:

public class MyFactory { // preferably this would implement an interface...
    private readonly MyClass _dependency;
    public MyFactory(MyClass dependency) {
        _dependency = dependency;
    }
    public Product CreateProduct() {
        return new Product(_dependency);
    }
}

Questo è esattamente cosa dovresti fare, almeno nella misura in cui usi una classe factory. Tutto ciò che sta accadendo qui è che stai implementando manualmente la funzione currying . Riscriviamolo in un modo diverso.

Func<MyClass, Action<Product>> CreateProduct 
    = (dependency) => () => new Product(dependency);

Ora

var factory = new MyFactory(new MyClass());
var product1 = factory.CreateProduct();
var product2 = factory.CreateProduct();

corrisponde a

var factory = CreateProduct(new MyClass());
var product1 = factory();
var product2 = factory();

Non sto dicendo che dovresti scrivere il tuo codice in questo modo invece che in quello precedente (anche se non sto dicendo che non dovresti )). Questo è solo un modello per spiegare cosa sta succedendo. In una lingua con oggetti ma non funzioni di ordine superiore, il modello di fabbrica è solo un'implementazione manuale di una chiusura . Nella programmazione funzionale nessuno parla del modello di fabbrica perché è solo un caso speciale non particolarmente degno di un aspetto onnipresente della programmazione funzionale.

    
risposta data 25.05.2017 - 17:22
fonte
-1

Vorrei memorizzare un riferimento al contenitore IoC in fabbrica e usarlo per creare prodotti piuttosto che usare la nuova parola chiave. I vantaggi di ciò sono che né la fabbrica né il chiamante devono più conoscere le dipendenze dei prodotti. Ancora più importante, le dipendenze dei prodotti e le dipendenze delle loro dipendenze possono ancora utilizzare il contenitore IoC. La nuova parola chiave nel pattern factory tende a interrompere l'uso di IoC.

D'altra parte se non hai bisogno di ciò, ciò che hai è migliore in quanto è più semplice. Non è così strano dal punto di vista concettuale che se X è necessario per creare un prodotto, la fabbrica responsabile della creazione di prodotti conosce anche X.

    
risposta data 25.05.2017 - 18:11
fonte

Leggi altre domande sui tag