Wal*_*rey 5 dependency-injection solid-principles
最近发现了依赖注入,我现在正试图掌握使用它的频率和距离。
例如,假设我有一个对话框,提示用户输入他们的注册详细信息——名字、姓氏、电话号码、序列号——诸如此类。应以各种方式验证数据(例如,名字和姓氏不为空,序列号为特定长度)。一旦通过验证,它应该被缓存在本地机器上,并发送到注册服务器。只有在所有这些事情都成功或用户取消后,该对话框才应关闭。
所以这可能是我们在这里尝试实现的四件事(职责):UI、验证、本地缓存、将数据发送到非本地服务器。
对话的职责是什么,应该注入什么?显然对话框是 UI,但是验证、缓存和数据发送都应该被注入吗?我认为他们这样做,否则对话框类必须知道数据字段背后的逻辑才能进行验证,它必须知道如何以及在何处缓存数据,以及如何将数据发送到某个地方。如果是这样,这可能会导致调用者端出现一些繁重的代码(假设我们通过构造函数进行注入,我认为这比 setter 函数更可取),例如
MyDialog dlg(new validator(), new cacher(), new sender());
Run Code Online (Sandbox Code Playgroud)
但也许这没问题?在多年看到诸如对话框之类的东西做所有事情的代码之后,它现在对我来说确实有点陌生。但我也可以看到这种情况如何迅速升级——如果还有其他各种各样的小事情需要做——有多少被注入的东西变得“太多”了?
请不要试图在示例场景中挑漏洞,我只是用它来说明。我对 DI 的原则更感兴趣,以及在什么时候你可能会走得太远。
嗯,你当然可以做到。注入验证很有意义,因为这样您就可以围绕验证代码编写单元测试,而无需启动任何 GUI 组件即可工作。注入缓存是有意义的,因为这样对话框就不必了解其界面之外的有关缓存系统的任何信息。注入发送者很有意义,因为您的对话不必对任何事情的进展有最模糊的了解。
我有把事情分开的习惯,因为我喜欢单一责任原则,而且我喜欢编写尽可能纯粹的代码。
问题是,当您注入太大的接口时,您不再有任何合理的想法,您所注入的东西可能实际上需要调用这些接口的哪些部分,并且交互变得复杂,您的单元测试开始依赖确切地说,依赖项会做什么,因为当您知道 75% 的接口不会被使用时,您就不会费心去模拟整个接口。
因此,一定要注入明显独立的职责的东西,但要确保以适当约束的方式设计它们的接口。类可以同时实现多个接口,因此您并不是不能将接口分割成小块,而是可以根据需要使用同一个对象来实现它们。依赖代码永远不必知道!
至于什么时候你走得太远了……真的很难说,但我认为你不会达到这一点,直到你使用一个根本不添加任何东西的界面注入一些东西。我总是想注入有副作用的东西,因为这对单元测试和保持事情更加合理有很大的帮助。如果您可以将业务逻辑拆分为纯类并注入它们,那么您将在为其编写单元测试时度过一段美好的时光,因此这可能是值得做的。
我使用这样的测试:
你的旅费可能会改变。
| 归档时间: |
|
| 查看次数: |
219 次 |
| 最近记录: |