2014-04-15 6 views
6

Lassen Sie uns annehmen, dass ich eine POCO Klasse, die foos und bars enthält:POCOs und Utility-Methoden

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; 
} 

In meinem Beispiel ich muss in der Lage sein foos und bars hinzuzufügen und zu entfernen:

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; 
} 

Aber nehmen wir an, dass ich auch die (willkürliche) Einschränkung, dass es eine foo pro bar und auch eine bar pro foo geben muss.

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) {...} 
} 

Meine Frage ist: Soll ich immer zu versuchen, eine POCO einfach zu halten und es nicht geben keine Hilfsmethoden aufgearbeitet? Das erste Beispiel POCO ist schön, weil es unveränderlich ist, und POCOs haben andere Vorteile. Ich kann jedoch keinen Weg sehen, die Klasse zu einem POCO zu machen und trotzdem Möglichkeiten zu haben, kontrolliert auf den Inhalt zuzugreifen und ihn zu modifizieren (zumindest nicht so, wie es scheint, als würde er übertöten). Einig

dachte, dass ich gehabt haben:

Nested modifizierende Klasse

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) {...} 
    ... 
    } 
} 

öffentliche verschachtelte Klasse? Nein Danke! Es ist auch genau so wie die Nicht-POCO-Klasse nur mit ein wenig mehr Verschachtelung.

Mit Zugriffsmodifikatoren

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) {...} 
    ... 
} 

Etwas besser, aber erfordert eine ganze Einheit des Einsatzes für jede POCO.

+1

Persönlich habe ich nichts dagegen, Dienstprogramm-Methoden auf Ihrem POCOs (auch wenn sie nicht wirklich POCOs mehr sind). Eine andere Option besteht darin, eine separate Erweiterungsmethodenbibliothek oder einen statischen PocoModifier zu erstellen, der sich außerhalb Ihrer POCOs befindet (Sie verschachteln also keine Klassen), aber die Machbarkeit hängt davon ab, ob Sie Ihren POCO einem Client aussetzen. – NWard

+0

Für mich scheint es, als ob Sie Geschäftslogik in Ihre Entitäten ziehen. Schreiben Sie die Geschäftslogik in eine separate Schicht. –

+0

Fühlt sich so an, als hätten Sie willkürliche Einschränkungen, die Sie persönlich auf Ihren Code anwenden wollten ... Vielleicht, wenn Sie darüber nachdenken, warum Sie es tun, können Sie es selbst entscheiden ... Randbemerkung: Ihr erstes Objekt ist nicht wirklich unveränderlich - Sie legen Listen offen, mit denen Sie beginnen möchten (erfordert Cast, aber wer wird dadurch gestoppt) und keine anderen Methoden anzeigen ... –

Antwort

12

Es klingt wie Ihre Daten würden besser durch etwas modelliert werden, das natürlich eine Foo mit einer Bar verbindet.

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

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

aus irgendeinem seltsamen Grund Sofern die Foo s und Bar s sind völlig voneinander getrennt mit Ausnahme der Anforderung, dass ihre Zählung gleich ist. Dann möchte ich Ihr drittes Beispiel ...

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 fügt unnötige Komplexität, meiner Meinung nach. Und verschachtelte Klassen sollten generell nicht öffentlich sein (also, wenn Sie die Klasse überhaupt haben, trennen Sie sie wie in Ihrem letzten Beispiel).

Wenn Sie eine POCO müssen mit so gut funktionieren (zB dass öffentlich zu Menschen mit Ihrem Code als Bibliothek belichten, während andere Logik internen halten), könnten Sie eine einfache POCO erstellen und anschließend Karte zu NotAPocoAnyMore mit AutoMapper (o.ä).

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

Ich gehe mit Repositories, um persistente POCOs (mit EF) zu behandeln.Hier ist ein Beispiel eines generischen Repository:

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 
    } 
} 

Und es ist Nutzung

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

Sie sind jetzt nicht Ihre POCOs muddying und haben ein Objekt speziell auf Ihre POCO beharren entworfen. Ich bin kein Fan von generischen Repositories - war gut für ein schnelles Beispiel. Sie können für jede Entität spezifische Repositories mit spezifischeren Abrufmethoden erstellen.

2

POCOs stellt nur eine Einheit von Daten/Informationen dar. Sobald Sie Regeln entweder als Einschränkung oder als Möglichkeit zur besseren Organisation Ihrer Daten erzwingen, beginnen Sie, das Verhalten Ihrer Daten zu definieren. Plötzlich haben Sie es nicht mehr mit POCOs zu tun und es wird zu einer ausgewachsenen Datenstruktur.

Wie Sie dies implementieren, bleibt Ihnen überlassen. Wenn Sie mit POCOs arbeiten möchten, können Sie Ihre Daten und das Verhalten mithilfe von Helpers/Extensions oder was auch immer Sie möchten trennen, oder Sie können Ihre eigene Datenstruktur erstellen, indem Sie die Daten und ihr Verhalten in einer einzigen Entität kombinieren.

Es ist nichts falsch mit beiden von ihnen und während einige Leute lieber mit POCOs arbeiten, bevorzuge ich normalerweise mit Data Structures arbeiten, die Daten und ihr Verhalten in einer einzigen Einheit kapselt.

Verwandte Themen