在静态方法中干净地访问子类的各个方面

时间:2014-06-04 09:26:50

标签: c# reflection

我正在编写一个类似ORM的基类,我需要根据子类中的信息改变行为。

例如,给定Person:OrmClass类,OrmClass中将有一些功能可以访问数据库表中的数据" person"使用静态方法Person.All()。我的模型是Ruby的ActiveRecord类,我觉得这个类比较干净。

我一直在以不同的方式看待它,但可以想到在面向对象的限制内没有干净的方法来实现它。在实例方法中很容易做到(当前类名称可以轻松访问)。但是All()"需要"作为一种静态方法,然后所有支持方法必须遵循静态土地。

我很感激任何建议。

1 个答案:

答案 0 :(得分:1)

将我的评论扩展为答案。您在此处遇到的是对静态方法和活动记录模式的限制的演示。静态方法是有限的,因为它们不能真正实现多态性,而活动记录模式是因为它迫使一个类承担它通常不应该承担的责任。 Person现在不仅要关注成为一个人,还要关注自己的数据访问。正如您已经意识到的那样,这个责任并不属于Person的实例,这就是为什么您不得不将一些非常重要的行为放入静态中。

避免这些问题的一种模式是存储库模式。在这里,您有PersonRepository来处理所有数据访问,并使Person成为一个人。 (您可能还想查看相关的工作单元模式)。

通常的实现方式会使Person完全不知道它是如何保留的,所以你不会在PersonRepository内对Person进行任何引用。所以给一个草图:

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成为一个抽象基类,并使用您需要子类的template method pattern - 特定信息(如执行所需的SQL查询所需的名称或参数)。

实体框架是此模式的一个流行示例,其中DbContext为其工作单元,DbSet<T>为其通用存储库。即使您想使用自己的实现,也可以将Entity Framework视为ORM设计的一个示例