我正在开发一个系统,该系统提供访问其数据库的 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
用于不同连接器(后面IConnectorAFactory
,IConnectorBFactory
接口)的方法——但实际上并没有任何东西需要工厂模式;我只有在实例化“控制器”对象时才知道什么。
此外,实际的连接器类本质上也需要派生,DatabaseConnection
因为它们需要相同的基本能力,然后(最迟)整个构造变得相当不祥。
我想我的想法在某个时刻走错了方向,现在完全走上了错误的轨道。这种解决方案的结构应该是什么样的?任何朝着正确方向的推动将不胜感激。
编辑:
@Tobias 的回答让我意识到我忘记了一个重要的细节:有两个不同版本的 Web 服务具有几乎相同的功能,但 API 完全不同,这也是必须对其进行封装的原因之一。
另一个问题是,如果我的逻辑类直接(或通过接口)访问 Web 服务,它们还关心构建 Web 服务查询的所有细节,这使得代码耦合更紧密(我们一直在生产到目前为止)并违反 SRP - 因此连接器接口的想法。