我正在努力更好地遵守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);
}
我在这里看到很多问题。
Database
做得太多了。Database
获取信息时,我都必须添加另一个Get方法来处理特定查询。我真的不知道正确的实施方式。我唯一真正的改进想法是数据库对象的某种基本接口,尽管它可能只对插入有帮助...
public interface IDatabaseObject
{
void Insert(Database db);
bool Delete(Database db);
}
实际实现这个的好方法是什么?
答案 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 ActiveRecord和NHibernate.