在静态方法中清晰地访问子类的各个方面



我正在编写一个类似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设计的示例

相关内容

  • 没有找到相关文章

最新更新