|
|
1
7
当您想要模拟对象与其合作者之间的交互时,接口非常有用。但是,对于具有内部状态的对象,接口中的值较小。 例如,假设我有一个与存储库对话的服务,以便提取某个域对象,以便以某种方式对其进行操作。 从存储库中提取接口具有明确的设计价值。我对存储库的具体实现很可能与NHibernate或ActiveRecord密切相关。通过将我的服务链接到接口,我完全脱离了这个实现细节。碰巧我也可以为我的服务编写超快的独立单元测试,现在我可以给它一个模拟IRepository了。 考虑到从存储库返回的域对象以及我的服务所作用的域对象,其价值较小。当我为我的服务编写测试时,我希望使用一个真正的域对象并检查其状态。例如,在调用service.AddSomething()之后,我想检查是否向域对象添加了内容。我可以通过简单地检查域对象的状态来测试这一点。当我单独测试我的域对象时,我不需要接口,因为我只需要对对象执行操作,并测试它的内部状态。e、 如果我的羊在睡觉,它吃草是合法的吗? 在第一种情况下,我们对 相互作用 基于测试。接口之所以有帮助,是因为我们想要截获被测对象与其具有mock的协作者之间传递的调用。在第二种情况下,我们感兴趣的是 基于测试。接口在这里没有帮助。试着意识到您是在测试状态还是交互,并让它影响您的接口或无接口决策。 请记住(如果您安装了Resharper的副本),以后提取接口非常便宜。如果您决定根本不需要该接口,那么删除该接口并恢复到更简单的类层次结构也很便宜。我的建议是从没有接口开始,当您发现想要模拟交互时,根据需要提取它们。 当你把IoC带到图片中时,我倾向于提取更多的接口——但尽量控制你把多少类塞进IoC容器中。一般来说,您希望将这些限制为基本上无状态的服务对象。 |
|
|
2
6
BDUF . 轻松使用coolade,让它自然流动。 |
|
|
3
6
请记住,虽然灵活性是一个值得追求的目标,但增加IoC和DI的灵活性(在某种程度上是TDD的要求)也会增加复杂性。唯一的灵活性是让下游的变化更快、更便宜或更好。每一个IoC/DI点都会增加复杂性,从而使其他地方的更改更加困难。 这实际上是你需要一个大的设计在前面 一些 范围:确定哪些领域最有可能发生变化(和/或需要广泛的单元测试),并在那里规划灵活性。重构以消除不太可能更改的灵活性。 现在,我并不是说你可以准确地猜测哪里需要灵活性。你错了。但你很可能会做对一些事情。当您以后发现不需要灵活性时,可以在维护中考虑到这一点。在您需要它的地方,可以在添加功能时将其考虑在内。 现在,可能改变或不改变的领域取决于您的业务问题和IT环境。这里有一些反复出现的地方。
但只有你才能判断什么可能改变,什么不应该改变。 |
|
|
4
5
我通常发现我想要“服务”的接口,而主要是“数据”的类型可以是具体的类。例如,我会有一个
不过我确实感觉到了你的痛苦-这有点像回到.h和.c文件的黑暗时代。。。 |
|
|
5
2
我认为最重要的“敏捷”原则是雅格尼(“你不需要它”)。换句话说,在实际需要之前不要编写额外的代码,因为如果提前编写,当(如果!)您最终需要它时,需求和约束可能已经发生了变化。 接口、依赖注入等等——所有这些都增加了代码的复杂性,使其更难理解和更改。我的经验法则是让事情尽可能简单(但不是更简单),并且不增加复杂性,除非它让我获得足够多的东西来抵消它带来的负担。 因此,如果您实际上正在测试并拥有一个mock对象,那么一定要定义一个mock类和real类都实现的接口。但是,不要纯粹基于假设的理由来创建一堆接口,即它在某些时候可能有用,或者它是“正确的”OO设计。 |
|
|
6
0
接口的目的是建立契约,当您希望动态更改执行任务的类时,接口特别有用。如果不需要更改类,接口可能会遇到阻碍。 有自动工具可以提取接口,因此您最好在以后的过程中延迟接口提取。 |
|
7
0
这在很大程度上取决于你提供什么。。。如果你在处理内部事务,那么“在需要之前不要做”的建议是合理的。但是,如果您正在制作一个供其他开发人员使用的API,那么在以后将其更改为接口可能会很烦人。 一个很好的经验法则是用任何需要成为子类的东西制作接口。这不是一种“在那种情况下总是制作一个接口”的事情,你仍然需要考虑它。
一些通常不是接口的类是只保存数据的类,比如处理x和y的Location类。实现这一目标的可能性很小。 |
|
|
8
-1
不要先创建接口-你不需要它们。您无法猜测哪些类需要接口,哪些类不需要接口。因此,现在不要花费任何时间用无用的接口来加重代码的负担。 但是,在重构步骤中,当您觉得迫切需要这样做时——当您看到需要一个接口时——提取它们。 |