代码之家  ›  专栏  ›  技术社区  ›  Will Eddins

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

  •  2
  • Will Eddins  · 技术社区  · 15 年前

    我在努力坚持 Single Responsibility Principle 更好,我也遇到了一些问题,比如如何构造与数据库通信的一般类设计。在简化版中,我基本上拥有一个数据库,其中包含:

    制造商<==探针<==>探针设置

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

    目前,以下是如何实现通信和对象的一般视图:

    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. 任何时候一个班级需要从 数据库 ,我必须添加另一个get方法来处理特定的查询。

    对于正确的实现是什么,我真的很茫然。我唯一真正需要改进的是某种数据库对象的基本接口,尽管它可能只对插入有帮助…

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

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

    2 回复  |  直到 15 年前
        1
  •  4
  •   Andrey Shchekin    15 年前

    在维护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,它就是数据访问。另外,对于数据库的每个复杂和可配置查询,您可能需要一个类。

        2
  •  2
  •   Alison R.    15 年前

    听起来你在找一个 ORM . 既然你在C工作,我想你有权 LinqToSQL 作为.NET框架的一部分。Linq可以做你想要做的事情,管理你的基础 CRUD 操作。同样值得检查的类似项目 Castle ActiveRecord NHibernate.