0

我正在开发一个系统,该系统提供访问其数据库的 Web 服务并通过 .NET 类公开它。我们通常的工作方式是在需要访问数据库并直接使用该实例时创建 Web 服务类的实例;这当然完全违背了 IoC 并创建了大部分不可测试的代码。我现在正在尝试设计一种使用 IoC 的新标准工作方式,以使我们能够编写(更多)SOLID 代码。

我目前的解决方案是这样的(解释得不是很好):

Web 服务封装在一个DatabaseConnection类中,该类将 Web 服务对象存储为受保护的成员,并提供对许多常用通用数据库调用的访问。

当我需要在实际应用程序中访问数据库时,我从该类派生(例如调用新类ApplicationDatabaseConnection)并在能够调用 Web 服务的方法中实现所需的数据库交互。

此类不直接在应用程序中使用,而是为应用程序的不同部分提供“连接器”接口,每个部分都由顶层的控制器/视图模型类表示。每当调用这些应用程序功能之一(例如从 UI)时,都会创建适当的控制器对象并将我的ApplicationDatabaseConnection对象作为相应“连接器”接口的实现传递,因此数据库访问在此时被正确封装和解耦据我所知。

我的问题是:虽然这是我在自己的代码中发现 ISP(接口隔离原则)实际使用的第一个案例(尽管我不确定这是否真的合理使用该概念),但我担心这个类可能做的太多而违反 SRP(单一责任原则)。还是“仅提供数据库访问权限,尽管针对许多不同的消费者”是一项单一职责?

为了让这一点更清楚一点,以下是相关类的大致样子:

DatabaseConnection
    protected m_webservice
    public OftenUsedDatabaseAccess()

ApplicationDatabaseConnection : DatabaseConnection, IConnectorA, IConnectorB
    public IConnectorA.RetrieveRecords(fieldValue)
    public IConnectorB.WriteStuff(listOfStuff)

FunctionAController
    private m_IConnectorA

FunctionBController
    private m_IConnectorB

我能想到的替代方案对我来说似乎也不理想。

为了拆分数据库访问功能,ApplicationDatabaseConnection该类只能是一个工厂类,其中包含Create用于不同连接器(后面IConnectorAFactoryIConnectorBFactory接口)的方法——但实际上并没有任何东西需要工厂模式;我只有在实例化“控制器”对象时才知道什么。

此外,实际的连接器类本质上也需要派生,DatabaseConnection因为它们需要相同的基本能力,然后(最迟)整个构造变得相当不祥。

我想我的想法在某个时刻走错了方向,现在完全走上了错误的轨道。这种解决方案的结构应该是什么样的?任何朝着正确方向的推动将不胜感激。

编辑:

@Tobias 的回答让我意识到我忘记了一个重要的细节:有两个不同版本的 Web 服务具有几乎相同的功能,但 API 完全不同,这也是必须对其进行封装的原因之一。

另一个问题是,如果我的逻辑类直接(或通过接口)访问 Web 服务,它们还关心构建 Web 服务查询的所有细节,这使得代码耦合更紧密(我们一直在生产到目前为止)并违反 SRP - 因此连接器接口的想法。

4

2 回答 2

0

为什么不直接创建一个接口,例如 MyWebService 并在调用您的服务的 MyWebServiceImpl 中实现它?可以公开与您的服务相同的方法并委托给它...

于 2012-02-18T00:23:50.520 回答
0

许多个月后,我知道“ApplicationDatabaseConnection”方法不仅违反了 SRP,而且还违反了 OCP,同时还阻碍了模块化。

我最终采用的路线有点类似于我描述的“工厂”替代方案——“主”DatabaseConnection 对象是一个子类,该子类也有一个“Create”方法,该方法将工厂用于特定的 DatabaseConnection 派生并且不关心它究竟创造了什么。这样,每个控制器都可以请求自己的连接对象,并且可以添加主应用程序不知道的控制器(即通过 MEF)。

于 2012-09-23T20:34:53.480 回答