我正在编写一个类似orm的基类,其中我需要根据子类中的信息更改行为。
例如,给定Person: OrmClass类,OrmClass中的功能可以使用静态方法Person. all()访问数据库表"Person"中的数据。我的模型是Ruby的ActiveRecord类,我觉得它提供了一个非常干净的比喻。
我一直在寻找不同的方法,但我想不出在面向对象的限制内实现它的干净方法。这在实例方法中很容易做到(其中当前类名很容易访问)。但所有()"需要"是一个静态方法,然后所有支持的方法必须遵循static-land。
将我的评论扩展为一个答案。您在这里遇到的是静态方法和活动记录模式的局限性的演示。静态方法是有限的,因为它们不能真正实现多态性,而活动记录模式是有限的,因为它迫使类承担通常不应该承担的责任。Person
现在不仅要关心作为一个人,还要管理自己的数据访问。正如你已经意识到的,这个责任并不真正属于Person
的实例,这就是为什么你不得不把一些相当重量级的行为放入静态。
PersonRepository
处理所有的数据访问,并留下Person
只是一个人。(您可能还需要查看相关的工作单元模式)。
通常的实现方式使Person
完全不知道它是如何持久化的,所以在Person
中不会有任何对PersonRepository
的引用。所以要给出一个草图:
public class PersonRepository
{
public IEnumerable<Person> All()
{
//Data access stuff here
}
//Other data access methods here
}
当你想要你的人,你从仓库开始。通常人们会有一个通用的基础存储库,如:
public class Repository<T>
{
public virtual IEnumerable<T> All()
{
//Data access stuff here
}
//Other data access methods here
}
如果您需要使用特定于个人的元素扩展或覆盖部件,那么您可以只执行PersonRepository : Repository<Person>
。
我不太确定你打算如何做你的数据访问,但潜在的作为一个起点,你可以使Repository
一个抽象基类,并使用模板方法模式,你需要子类特定的信息(如名称或参数执行所需的sql查询)。
Entity框架是这种模式的一个流行示例,DbContext
是它的工作单元,DbSet<T>
是它的通用存储库。即使您想使用自己的实现,您也可以查看实体框架作为ORM设计的示例