遵循单一责任原则设计数据库交互

时间:2010-01-20 21:20:20

标签: c# database design-patterns class single-responsibility-principle

我正在努力更好地遵守Single Responsibility Principle,并且我在掌握如何构建与数据库通信的通用类设计时遇到了问题。在简化版本中,我基本上有一个包含以下内容的数据库:

  

制造商< ==探针< ==> ProbeSettings

探针有制造商。探针有一组设置。在整个应用程序中访问相关对象,坦率地说,当前的实现是一团糟。

目前,这里是关于如何实现通信和对象的一般视图:

public class Manufacturer
{
  public int ID; // Primary key, auto-incrementing on insert
  public string Name;
}

public class Probe
{
  public int ID; // Primary key, auto-incrementing on insert
  public int ManufacturerID;
  public string Name;
  public int Elements;
}

public class ProbeSettings
{
  public int ProbeID; // Primary key, since it is unique.
  public int RandomSetting;
}

// This class is a mess...
public static class Database
{
  public static string ConnectionString;

  public static void InsertManufacturer(Manufacturer manuf); // ID would be ignored here, since it's auto-incrementing.
  public static void InsertProbe(Probe probe); // Again, ID generally ignored.
  public static void InsertProbeSettings(ProbeSettings probeSet);

  public static Manufacturer[] GetAllManufacturer();
  public static Probe[] GetProbesFromManufacturer(int manufacturerID);
  public static Probe[] GetProbesFromManufacturer(Manufacturer manuf);
}

我在这里看到很多问题。

  1. Database做得太多了。
  2. 这些对象在真正读取时可以是不可变的,唯一的问题是插入后,我不确定它们被分配了什么ID,插入的对象现在已经过时了。
  3. 每当班级需要从Database获取信息时,我都必须添加另一个Get方法来处理特定查询。
  4. 我真的不知道正确的实施方式。我唯一真正的改进想法是数据库对象的某种基本接口,尽管它可能只对插入有帮助...

    public interface IDatabaseObject
    {
        void Insert(Database db);
        bool Delete(Database db);
    }
    

    实际实现这个的好方法是什么?

2 个答案:

答案 0 :(得分:4)

在维护SRP(或任何其他类型的理智模式)的同时使用DB的最佳解决方案是使用某种ORM(例如,NHibernate)。

这将允许您按原样使用类,而不是手动将它们从/向DB中抛出。

例如,对于NH,您的类可以如下所示:

public class Manufacturer
{
  public string Name { ... }
  public IList<Probe> Probes { ... }
}

public class Probe
{
  public string Name { ... }
  public int Elements { ... }
  public ProbeSettings Settings { ... }
}

public class ProbeSettings
{
  public int RandomSetting;
}

如您所见,您已经不需要GetProbesFromManufacturer,因为您可以在制造商中导航集合。

此外,ORM将管理对象ID并为您保存。因此,您需要的只是一小部分固定数量的通用方法,如LoadById / LoadAll,它非常适合类SRP,即数据访问。此外,您可能需要每个复杂的类和可配置的DB查询。

答案 1 :(得分:2)

听起来你正在寻找ORM。由于您使用的是C#,我假设您可以访问LinqToSQL作为.NET框架的一部分。在管理基本的CRUD操作方面,Linq可以做您正在寻找的事情。类似的项目,也值得一试,是Castle ActiveRecordNHibernate.