Domanda

mi è stato sempre più familiarità con il modello di fabbrica (con modello di strategia) e quello che un grande vantaggio il modello può avere. Tuttavia, ho lottato con la seguente situazione:

In precedenza, avrei fatto qualcosa come il seguente, dove c'è una classe dirigente che avrebbe costruire e salvare un auto. Non c'è l'iniezione di dipendenza qui ed è una scarsa applicazione, soprattutto quando si cerca di test di unità.

public class CarManager
{
    public static Car GetCarFromDatabase(int carId) { return new Car(); }

    public static void SaveCar(Car car) { }
}

Ora vedo come avrei potuto avere Factories diverso che le auto di build per me, sia che si tratti di un database, o dovunque! Questo è grande! Quindi, ecco la mia domanda:

Q1: E 'la mia comprensione che Factories dovrebbe solo Crea oggetti, è corretto? Se è così, per quanto riguarda la seconda domanda?

Q2: Se io sono seguendo il modello di fabbrica per la costruzione di miei oggetti, come devo fare per salvare i miei oggetti? C'è un modello diverso per questo, o sto non comprendendo completamente il modello di fabbrica?

È stato utile?

Soluzione

Il fabbrica modello si suppone per aiutare con la creazione di oggetti. È per questo che è classificato come un modello "Creazione". Per rispondere alla tua prima domanda, non dovrebbe essere usato per persistere oggetti.

Il modello Repository è un modello di persistenza che deve essere utilizzato per il salvataggio di oggetti a qualche meccanismo di persistenza o il recupero di dati da un meccanismo di persistenza. Questo è in realtà, secondo Martin Fowler, un modello di impresa che dovrebbe essere affrontato diverso rispetto al tipico pattern di progettazione.

Quando si pensa alla tua domanda, si vuole guardare il S principio SOLID in cui si afferma che una classe deve avere un unico responsabile, il che significa che dovrebbe avere un unico motivo per cambiare. In questo caso, quando si parla di un oggetto che crea oggetti e salva come (persiste) loro, si dispone di una classe che ha due ragioni per il cambiamento. Ora, potrebbe sembrare che potrebbe essere un singolo responsabilità perché un repository può recuperare e salvare gli oggetti nella vostra applicazione e il recupero può apparire come una fabbrica (e spesso è un oggetto di fabbrica all'interno del repository), ma in quello che stai descrivendo , l'oggetto ha uno troppe responsabilità.

Altri suggerimenti

di fabbrica non dovrebbe essere il salvataggio dei dati. Un Data Access Object (DAO) o un tavolo mapper sarebbe un'idea migliore.

Tutto dipende dalle vostre esigenze e come si vuole fare le cose, i modelli sono pratiche non standard, che incoraggiano per il riutilizzo del codice, i modelli non sono prese sulla pietra. Quindi, perché non si dovrebbe usare modello di fabbrica per rendere gli oggetti persistenza ?. Questo è il modo che ho usato come modello per risolvere il problema di leggere / scrivere dati da / a diversi database, forse questo non è il meglio sotto forma di utilizzare il modello ma sta attualmente lavorando, è estensibile, è distribuito tra gli strati, e quasi tutti possono capirlo:

namespace Domain.App
{
    public class PresentationClass
    {
        private Collection<ISomeOutput> GetData(ISomeInput1 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier );
            return logic.GetSomeData(input) as Collection<ISomeOutput>;
        }
        private IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {   
            ServicesLogicContext logic = new ServicesLogicContext( (MyType) Identifier);
            return logic.ExecuteSomeAction(input);
        }
    }
}   

namespace Domain.Logic
{
    public sealed class ServicesLogicContext : ServicesLogicContextBase
    {
        public IList<ISomeOutput> GetSomeData(ISomeInput1 input) 
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            return DBServicesProvider.GetSomeData(input);
        }
        public IMethodResult ExecuteSomeAction(ISomeInput2 input)
        {
            DBServices services = DBServicesProvider.CreateServices(SomeIdentifier);
            IMethodResult result = services.ExecuteSomeAction(input);
            return result;
        }
    }
}

namespace Domain.Data
{
    public abstract class DBServices : IServices
    {
        public virtual IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public virtual IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific1 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public class DBServicesSpecific2 : DBServices
    {
        public override IList<ISomeOutput> GetSomeData(ISomeInput1 input)  {...}
        public override IMethodResult ExecuteSomeAction(ISomeInput2 input) {...}
    }

    public sealed class DBServicesProvider
    {
        public static DBServices CreateServices(MyType identifier)
        {
            DBServices result = null;       
            switch(identifier) 
            {
                case MyType.Specific1: result = new DBServicesSpecific1(); break;
                case MyType.Specific2: result = new DBServicesSpecific2(); break;       
            }
            return result;
        }
    }
}

In generale, penso che ci si sta avvicinando questo dal punto di vista sbagliato.

È necessario identificare il problema che si sta tentando di risolvere, e quindi cercare soluzioni che si adattano questo problema. Sembra a me più come hai scoperto un determinato modello, e quindi stanno cercando di applicarlo ad ogni problema si verifica.

L'unico problema si parla con il codice che hai postato è che non è facile per unit test. Una soluzione per rendere le classi più verificabili è quello di invertire le loro dipendenze. Quindi mi sento di iniziare a guardare a ciò che le altre classi questa classe dipende, e iniziare a fare quelle dipendenze iniettabili. Come punto di partenza, vi consiglio di leggere su di inversione di dipendenza / inversione di controllo.

Q1 - modello Sì, fabbrica deve essere utilizzato in posizione ideale per la creazione di oggetti. Quindi, è possibile creare l'oggetto auto utilizzando il modello di fabbrica.

Q2 - Per comprimere il vostro oggetto macchina non si dovrebbe usare il modello di fabbrica. Disaccoppiare la creazione di oggetti Car e salvare l'oggetto auto. Ed è difficile suggerire un modello di progettazione per salvare l'oggetto auto senza capire le esigenze di precisione. A mio parere, se avete solo bisogno di salvare la vostra auto oggetti allora tutto ciò che forse bisogno è un metodo di salvataggio nella classe auto manager. Non più di design pattern di utilizzo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top