让我们假设我有一个包含foos和bars的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; }
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; }
但是我要说我还需要(任意)约束,每个条形图必须有一个foo,每个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) {...} ... }
稍微好一些,但每个POCO需要一个完整的部署单元.
解决方法
听起来你的数据会更好地通过将Foo与Bar配对的东西来建模.
public class Poco { public IList<Tuple<Foo,Bar>> FooBars { get { return fooBars; } } private List<Tuple<Foo,Bar>> fooBars; }
除非出于某些奇怪的原因,Foos和Bars完全分开,除非要求它们的计数相同.然后我喜欢你的第三个例子……
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) {...} }
在我看来,PocoModifier增加了不必要的复杂性.嵌套类通常不应该是公共的(所以如果你有类,那么就像在上一个例子中那样分开).
如果你需要一个POCO也可以使用(比如公开给那些使用你的代码作为库的人,同时保持其他逻辑内部),你可以创建一个普通的POCO,然后用AutoMapper(或类似的)将它映射到NotAPocoAnyMore .
public class Poco { public IList<Foo> Foos { get; set; } public IList<Bar> Bars { get; set; } }