2014-04-15 12 views
6

lascia supporre che ho una classe POCO che contiene foos e bars:pocos e di utilità metodi

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 
} 

Nel mio esempio ho bisogno di essere in grado di aggiungere e rimuovere foos e bars:

public class Poco { 
    public IList<Foo> Foos { get { return foos; } } 
    public IList<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 
} 

Ma diciamo che ho anche bisogno del vincolo (arbitrario) che ci deve essere uno foo per bar e anche uno bar per foo.

public class NotAPocoAnyMore { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
} 

mia domanda è questa: Sto ottenendo a lavorato su di cercare di mantenere una semplice POCO e non dare alcun metodo di utilità? Il primo esempio di POCO è bello perché è immutabile e i POCO hanno altri vantaggi. Tuttavia, non riesco a vedere un modo per mantenere la classe un POCO e avere ancora i modi per accedere e modificare i contenuti in modo controllato (almeno non in un modo che non sembra eccessivo).

Alcuni pensato che ho avuto:

nidificati classe modifica

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 
    public PocoModifier Modifier { get { ... } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public class PocoModifier { 
    private readonly Poco toModify; 
    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
    ... 
    } 
} 

classe annidata pubblici? No grazie! Inoltre è proprio uguale alla classe non POCO solo con un po 'più di nidificazione.

Uso modificatori di accesso

public class Poco { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 
    public PocoModifier Modifier { get { ... } } 

    internal List<Foo> foos; 
    internal List<Bar> bars; 
} 

public class PocoModifier { 
    private readonly Poco toModify; 
    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
    ... 
} 

leggermente migliore, ma richiede una intera unità di distribuzione di ciascun Poco.

+1

Personalmente non mi interessa avere metodi di utilità sui POCO (anche se non sono più POCO). Un'altra opzione è quella di creare una libreria di metodi di estensione separata o PocoModificatore statico che è esterno ai POCO (quindi non si annidano le classi), ma la fattibilità dipende da se si espone il POCO a un client. – NWard

+0

Per me sembra che tu tiri la logica del business nelle tue entità. Scrivi la logica aziendale in un livello separato. –

+0

Sembra che tu abbia stabilito restrizioni arbitrarie che hai deciso di forzare sul tuo codice ... Forse se pensi al motivo per cui lo fai puoi decidere da solo ... Nota a margine: il tuo primo oggetto non è davvero immutabile - stai esponendo gli elenchi per iniziare (richiede il cast, ma chi verrà fermato da quello) e non mostrando altri metodi ... –

risposta

12

Sembra che i tuoi dati siano meglio modellati da qualcosa che naturalmente accoppia uno Foo con uno Bar.

public class Poco { 
    public IList<Tuple<Foo, Bar>> FooBars { get { return fooBars; } } 

    private List<Tuple<Foo, Bar>> fooBars; 
} 

A meno che per qualche strana ragione sono completamente separati tranne che per il requisito che il loro conteggio è lo stesso delle Foo s e Bar s. Poi mi piace il tuo terzo esempio ...

public class NotAPocoAnyMore { 
    public IEnumerable<Foo> Foos { get { return foos; } } 
    public IEnumerable<Bar> Bars { get { return bars; } } 

    private List<Foo> foos; 
    private List<Bar> bars; 

    public void Add(Foo f, Bar b) {...} 
    public void Remove(Foo f, Bar b) {...} 
} 

PocoModifier aggiunge inutili complessità, a mio parere. E le classi nidificate in genere non dovrebbero essere pubbliche (quindi se hai la classe affatto, rendila separata come nel tuo ultimo esempio).

Se avete bisogno di un POCO di lavorare con così (ad esempio, per esporre che pubblicamente a persone che utilizzano il codice come una biblioteca, mantenendo altra logica interna), è possibile creare un POCO pianura e poi map a NotAPocoAnyMore con AutoMapper (o simili).

public class Poco { 
    public IList<Foo> Foos { get; set; } 
    public IList<Bar> Bars { get; set; } 
} 
0

Vado con repository per gestire POCO persistenti (utilizzando EF).Ecco un esempio di un repository generico:

public interface IRepository<T> 
{ 
    void Add(T entity); 
    void Remove(T entity); 
    ... 
} 

public class Repository<T> : IRepository<T> 
{ 
    // dbset or list or whatever you're persisting to 

    public void Add(T entity) { 
     // add to dbSet 
    }  
    public void Remove(T entity) { 
     // remove from dbSet 
    } 
} 

Ed è l'utilizzo

var repo = new Repository<User>(); 
repo.Add(new User()); 

Ora non è confondere i vostri pocos e avere un oggetto specificamente progettato a persistere tuo POCO. Non sono un fan dei repository generici - è stato utile per un rapido esempio. È possibile creare repository specifici per ciascuna entità con metodi di recupero più specifici.

2

POCO rappresenta solo un'unità di dati/informazioni. Una volta che inizi ad applicare le regole come un vincolo o come un modo per organizzare meglio i tuoi dati, inizi a definire il comportamento dei tuoi dati. Improvvisamente, non hai più a che fare con POCO e diventa una vera e propria struttura dati.

Come si implementa questo dipende da voi. Se vuoi lavorare con POCOs, puoi separare i tuoi dati e il comportamento usando Helpers/Extensions o qualsiasi altra cosa tu voglia o puoi costruire la tua Data Structure combinando i dati e il loro comportamento in una singola entità.

Non c'è niente di sbagliato in entrambi e mentre alcune persone preferiscono lavorare con POCO, di solito preferisco lavorare con Data Structures che incapsula i dati e il loro comportamento in una singola entità.

Problemi correlati