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

发布于 2024-08-18 18:02:58 字数 1696 浏览 2 评论 0原文

我试图更好地遵守单一责任原则,但我在掌握如何构建与数据库通信的通用类设计。在简化版本中,我基本上有一个数据库,其中包含:

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

探针有一个制造商。探头有 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. 数据库 做的事情太多了。
  2. 这些对象在真正读取时可以是不可变的,唯一的问题是插入后,我不确定它们被分配了什么 ID,并且插入的对象现在已过时。
  3. 每当类需要从数据库获取信息时,我都必须添加另一个 Get 方法来处理特定查询。

我真的不知道什么是正确的实现。我唯一真正的改进想法是数据库对象的某种基本接口,尽管它可能只对插入有帮助......

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

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

I'm trying to adhere to Single Responsibility Principle better, and I'm having issues grasping how to structure the general class design for communicating with a database. In a simplified version, I essentially have a database containing:

Manufacturer <== Probes <==> ProbeSettings

A probe has a manufacturer. A probe has 1 set of settings. The related objects are accessed all over the application, and quite frankly, the current implementation is a mess.

Currently, here's a general view of how communication and objects are implemented:

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);
}

I see many issues here.

  1. Database does far too much.
  2. These objects can be immutable when read really, the only issue is after inserting, I'm not sure what ID they were assigned, and the inserted object is now obsolete.
  3. Anytime a class needs to get information from the Database, I'd have to add another Get method to handle a specific query.

I'm really at a loss here on what a correct implementation would be. My only real idea for improvement is some kind of base interface for database objects, although it might only help for inserts...

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

What is a good way to actually implement this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡墨 2024-08-25 18:02:58

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

这将允许您按原样使用类,而不是手动将它们从数据库中扔出/扔到数据库中。

例如,对于 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 因为您只需导航Manufacturer 中的集合即可。

此外,ORM 还将管理对象 ID 并为您保存。因此,您所需要的只是少量固定数量的通用方法,例如 LoadById/LoadAll,它们非常适合数据访问的类 SRP。此外,您可能需要为数据库的每个复杂且可配置的查询提供一个类。

Well the best solution to work with DB while maintaining SRP (or any other kind of sane pattern) is to use some kind of ORM (for example, NHibernate).

This will allow you to work with classes as they are, instead of manually tossing them from/to DB.

For example, with NH your classes can look like this:

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;
}

As you see, you already do not need GetProbesFromManufacturer since you can just navigate the collection within Manufacturer.

Also, ORM will manage object ids and saving for you. So all that you will need will be just a small and fixed number of general methods like LoadById/LoadAll, which fit nicely into a class SRP of which is data access. Also you would probably need a class per each complex and configurable query to the DB.

方觉久 2024-08-25 18:02:58

听起来您正在寻找 ORM。由于您使用 C# 工作,我假设您有权访问 LinqToSQL< /a> 作为 .NET 框架的一部分。 Linq 可以满足您的需求,管理您的基本 CRUD运营。类似的项目也值得一看,有 Castle ActiveRecordNHibernate。

It sounds like you are looking for an ORM. Since you're working in C#, I'll assume you have access to LinqToSQL as part of the .NET framework. Linq can do what you're looking for as far as managing your basic CRUD operations. Similar projects, also worth checking out, are Castle ActiveRecord and NHibernate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文