POCO和实用方法

本文关键字:方法 POCO | 更新日期: 2023-09-27 17:58:40

假设我有一个包含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;
}

但假设我还需要(任意)约束,即每个bar必须有一个foo,每个foo也必须有一个子bar

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部署一个完整的单元。

POCO和实用方法

听起来您的数据最好由FooBar自然配对的东西来建模。

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

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

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

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

我使用存储库来处理持久化的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,并且有一个专门设计的对象来持久化你的POCO。我不喜欢通用存储库——这是一个很好的例子。您可以使用更具体的检索方法使存储库特定于每个实体。