2012-05-09 12 views
40
  1. Un buon esempio di modello di fabbrica astratto in C#?
  2. Quali sono i vantaggi del modello Abstract factory in C#?
  3. Come utilizzare i generici C# con il pattern Factory astratto?
  4. Come testare unitamente al pattern Factory astratto?
+1

http://www.dofactory.com/Patterns/PatternAbstract.aspx – Habib

+2

Le domande dovrebbero essere più specifico. Sembra, come se tu non volessi trovare informazioni sul tuo argomento, e vuoi solo che qualcuno ti spieghi l'argomento. –

+0

Inoltre puoi studiare altri pattern in contrasto con Abstract Factory Pattern. http://www.dofactory.com/Patterns/Patterns.aspx –

risposta

123

Prima di tutto, ti suggerisco di leggere il modello Abstract Factory, ad esempio here. Ora proverò a spiegare perché useresti questo schema.

Normalmente, se si utilizza il modello di fabbrica, verranno creati oggetti in una fabbrica. Il problema sorge quando si hanno più implementazioni di una data classe (o classi). Ora, quelle implementazioni multiple sono raggruppate. Si utilizzerà Abstract Factory pattern quando si dispone di una fabbrica, ma si desidera raggruppare la creazione di oggetti per gruppo.

Ok, la spiegazione sopra potrebbe non essere completamente chiara, quindi ti fornirò un esempio.

Supponiamo di disporre di una libreria di classi con agenti di dati. Gli agenti di dati forniscono metodi per accedere e archiviare dati diversi. Certo, ci sono molti modi per archiviare i tuoi dati. Ad esempio: in un database, in un file XML, su un servizio,. Per ognuno di questi possibili modi, ti piacerebbe avere agenti di dati. Ora il problema è che non si vuole che qualcuno usi DataAgentA per i file XML insieme a DataAgentB per il database (supponiamo di avere le entità A e B). L'utente deve utilizzare solo un motore di archiviazione.

Lascia che ti presenti il ​​modello di Fabbrica astratta.

Assicuratevi che gli utenti non possano creare direttamente un'istanza dei vostri agenti di dati, ma dovranno estrarre questi agenti da una fabbrica. (Un ulteriore vantaggio è che quando si utilizza ad esempio un database (EF), è possibile eseguire il cablaggio interno per assicurarsi che i propri agenti di dati utilizzino lo stesso contesto, ecc.). Come si fa a realizzare questo? Impostiamo il costruttore dei nostri agenti di dati su "interno". Oltre a ciò, creiamo diverse fabbriche per ciascun motore di archiviazione. Ora, dato che quelle fabbriche fanno tutte la stessa cosa, abbiamo anche queste interfacce (proprio come i nostri agenti di dati, dal momento che tutti devono fare lo stesso, giusto !?).

Di seguito abbiamo le nostre interfacce. Fondamentalmente questo è lo schema di fabbrica, ma solo ora invece delle circa classi, stiamo parlando di interfacce .

public interface IAgentA 
{ 
    // Add some methods here! 
} 

public interface IAgentB 
{ 
    // Add some methods here! 
} 

public interface IAgentFactory 
{ 
    IAgentA CreateAgentA(); 
    IAgentB CreateAgentB(); 
} 

Ora, per i due agenti, abbiamo due implementazioni possibili, uno per XML e uno per l'archiviazione di database (di nuovo: questo è un esempio, si può avere il maggior numero di tipi di implementazione come volete). Queste implementazioni apparirebbero come questa (vedi sotto). Nota che ho creato il costruttore internal! Questo è necessario per la parte che viene dopo questo blocco di codice.

public class AgentA_Xml : IAgentA 
{ 
    internal AgentA_Xml() 
    { /* Construction here */} 

    // IAgentA method implementations 
} 

public class AgentB_Xml : IAgentB 
{ 
    internal AgentB_Xml() 
    { /* Construction here */} 

    // IAgentB method implementations 
} 


public class AgentA_Database : IAgentA 
{ 
    internal AgentA_Database() 
    { /* Construction here */} 

    // IAgentA method implementations 
} 

public class AgentB_Database : IAgentB 
{ 
    internal AgentB_Database() 
    { /* Construction here */} 

    // IAgentB method implementations 
} 

Ora come i costruttori sono interni. Questo fa sì che non è possibile istanziare tali classi al di fuori dell'assembly, che generalmente è ciò che si fa con questo tipo di casi. Ora dobbiamo creare le nostre fabbriche.

public class XMLAgentFactory : IAgentFactory 
{ 
    public IAgentA CreateAgentA() 
    { 
     return new AgentA_Xml(); 
    } 

    public IAgentB CreateAgentB() 
    { 
     return new AgentB_Xml(); 
    } 
} 


public class DatabaseAgentFactory : IAgentFactory 
{ 
    public IAgentA CreateAgentA() 
    { 
     return new AgentA_Database(); 
    } 

    public IAgentB CreateAgentB() 
    { 
     return new AgentB_Database(); 
    } 
} 

Poiché entrambe le fabbriche implementano l'interfaccia IAgentFactory, l'utente può facilmente cambiare di AgentFactory attuazione (se, in questo caso, vuole usare un motore di memorizzazione differente) senza dover modificare qualsiasi altro codice scrive (contro gli agenti), purché programmato contro le interfacce (ovviamente).

Sopra la spiegazione spero che risponda alle vostre domande (1) e (2).

  1. esempio Per astratto modello di fabbrica in C#?
  2. e quali sono i vantaggi del modello Abstract factory in C#?

Rispondere alla domanda (3).

  1. Come utilizzare i generici C# con il modello di fabbrica Astratto?

è ancora possibile utilizzare farmaci generici, questo non cambia qualsiasi bit quando si utilizza un modello astratto di fabbrica. Naturalmente, dovrai creare metodi generici di fabbrica (i metodi di creazione), ma non dovrebbe esserci alcun problema.

Rispondere alla domanda (4).

  1. Come test di unità con astratto modello di fabbrica?

Proprio come si farebbe con test di unità ogni altra classe. Solo una cosa sarà diversa.

Dato che probabilmente si desidera testare il costruttore delle classi (e forse anche altri metodi interni), è necessario rendere i costruttori interni (metodi) visibili al progetto di test dell'unità (e non si desidera modificare il internal a public). Questo è fatto facilmente aggiungendo la seguente riga al AssemblyInfo.cs del file del progetto (il progetto in cui la vostra fabbrica e le classi sono in):

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("My.UnitTest.Namespace")] 

Potete trovare ulteriori informazioni (e osservazioni) sull'attributo InternalsVisibleTo su MSDN .

Spero che questo tipo di risposta alla tua domanda.

+1

Questa risposta è una di quelle gemme nascoste che la gente parlare di alcuni momenti. Molto ben spiegato. Grazie. – ppumkin

Problemi correlati