2014-04-15 18 views
6

让我们假设我有一个包含foosbars一个POCO类:波苏斯和实用方法

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

在我的例子中,我需要能够添加和删除foosbars

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

但是可以说我还需要(每barbar每个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) {...} 
} 

我的问题是:我是否获得对调动起来努力保持POCO简单,并没有给它任何实用方法?第一个例子POCO很好,因为它是不可变的,POCO还有其他优点。然而,我看不到一种让班级成为POCO的方式,并且仍然有办法以受控的方式访问和修改内容(至少不是看起来过度杀戮的方式)。

有些人认为我有:

嵌套类修改

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

公共嵌套类?不用了,谢谢!此外,它的确与非POCO课程只是多一点嵌套相同。

使用访问修饰符

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

稍微好一点,但需要部署的每个POCO的一个整体。

+1

就我个人而言,我并不介意在您的POCO上使用实用方法(即使它们不再是真正的POCO)。另一种选择是创建一个单独的扩展方法库或静态PocoModifier,它是POCO外部的(因此您不是嵌套类),但是可行性取决于您是否将POCO公开给客户端。 – NWard

+0

对我来说,你似乎将业务逻辑拉入你的实体。将业务逻辑写入单独的层。 –

+0

感觉就像你有一套任意的限制,你个人决定强制你的代码...也许如果你想到你为什么这样做,你可以自己决定...注意:你的第一个对象并不是真正不可变的 - 您正在公开列表(需要投射,但是谁将被阻止)并且不显示任何其他方法... –

回答

12

这听起来像你的数据会更好地模拟一些东西,自然配对FooBar

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

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

除非出于某种奇怪的原因Foo S和Bar s为除了他们的数量是相同的要求完全独立。然后,我喜欢你的第三个例子......

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增加了不必要的复杂性,在我看来。嵌套类通常不应该公开(所以如果你有类,就像上一个例子那样分开)。

如果你需要一个POCO与以及合作(如以露出公开使用您的代码库的人,同时保持其他逻辑内),您可以创建一个简单的POCO,然后将其与AutoMapper映射到NotAPocoAnyMore (或类似)。

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

我用存储库去处理持续的POCO(使用EF)。这是一个通用的存储库的例子:

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

而且它的使用

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

现在不弄脏你波苏斯并有一个对象专门设计的,以保存POCO。我不是通用版本库的粉丝 - 对于一个简单的例子来说,它是个不错的选择。您可以使用更具体的检索方法为每个实体制作特定的存储库。

2

POCOs只代表一个数据/信息单位。一旦开始执行规则作为约束或作为更好地组织数据的方式,您就开始定义数据的行为。突然间,你不再处理POCO,它变成了一个完整的数据结构。

您如何实施这取决于您。如果你想使用POCO,你可以通过使用Helpers/Extensions或者你喜欢的任何东西来分隔你的数据和行为,或者你可以通过将数据和它的行为合并到一个实体中来构建你自己的数据结构。

其中任何一个都没有问题,虽然有些人更喜欢使用POCO,但我通常更喜欢使用封装数据的数据结构以及它在单个实体中的行为。