好吧,现实生活中的应用程序就是这样复杂的。在不知不觉中,您想用 App 替换 UI,将您的逻辑公开为 WCF 服务,用另一个服务提供商更改电子邮件服务,在模拟 DAL 的同时测试您的代码片段,并用另一个更改数据库.
处理这个问题的常用方法是通过将实现与调用者分开的接口传递所有调用。之后,您可以实现不同的 DAL。
我个人通常采用这种方法:
- 首先创建一个包含所有接口的 DLL。基本上,这个想法是通过界面公开您的 UI、应用程序或任何需要的所有调用。从现在开始,您的 UI 不再与数据库或电子邮件提供商对话。
- 如果您需要访问接口,则使用工厂模式。永远不要使用“新”;从长远来看,这会给你带来麻烦。
- 创建它并非易事,需要适当的制作。通常我从最低版本开始,将 UI 中的所有其他内容作为第一个版本进行修改,然后在创建界面的同时将所有涉及数据库或服务的内容移动到正确的项目中,最后重新设计所有内容,直到我 100% 满意.
- 接口应经久耐用。当然,随着时间的推移会发生变化,但你真的想尽量减少这些。想想未来会怎样,阅读其他人的想法,并确保你的界面反映了这一点。
基本上,您现在拥有一个可以与单个数据库、邮件提供商等一起使用的工作软件。到目前为止一切都很好。
接下来,重新设计工厂。基本上,您希望使用配置设置为您的数据选择正确的提供程序(实现您的接口的正确 DLL)。在大多数情况下,一个简单的开关就足够了。
在这一点上,我通常养成为接口进行大量单元测试的习惯。
最后一步是为不同的数据库提供程序创建 DLL。其中之一将在您的应用程序运行时加载。
我更喜欢简单的 Linq 而不是 SQL(我也使用来自 LinqConnect 的库),因为它非常快。我只是从复制粘贴另一个数据库提供程序开始,然后重新设计它直到它工作。就我个人而言,我不再相信神奇的“支持所有 sql 数据库”解决方案:根据我的经验,某些数据库处理某些查询的速度比其他数据库快得多 - 这意味着您最终可能会得到一些自定义代码反正每个数据库。
这也是您的单元测试真正获得回报的地方。基本上,您可以从复制粘贴开始并进行测试。如果你幸运的话,一切都会以不错的表现立即运行......如果没有,你知道从哪里开始。
经久耐用
建立持久的东西。事情会改变:
- 考虑更新并测试它们。更喜欢自动测试。
- 你不想每天都在修补你的工厂。使用反射、表达式、代码生成或任何你的毒药来省去更改代码的麻烦。
- 花时间编写测试。确保覆盖大部分。这一点我怎么强调都不为过;在压力下,人们通常不写测试来“节省”时间。您会注意到,这一次您的“保存”将在您上线后加倍支持您。每个月。
实体框架呢
我已经看到很多客户因此而在性能方面遇到麻烦。在我测试它的许多次中,我有同样的经历。我注意到客户围绕 EF 进行大量查询以获得一些不错的性能。
公平地说,我几年前就放弃了,我知道他们已经取得了相当大的性能改进。尽管如此,我还是会在考虑之前对其进行测试(尤其是复杂的查询)。
如果我要使用 EF,我会在“数据库公用 DLL”中实现所有 EF 内容,然后从中派生类。正如我所说,并非所有数据库都与查询相同 - 您可能希望实施一些获得良好性能所必需的技巧。你的测试会告诉你。
奖金
通过接口编程的其他原因与代理相结合有很多优势。仅举几例,您可以通过简单地实现相同的接口轻松创建日志接收器、缓存、统计信息、WCF 等。如果有一天你讨厌你当前的 OR 映射器,你可以把它扔掉,而不用触及应用程序的任何一行。