您何时鼓励对界面进行编程而不是直接针对具体类进行编程?
我遵循的准则是在代码需要跨越逻辑/物理边界时创建抽象,尤其是在涉及与基础架构相关的问题时。
另一个检查点是,由于可能存在额外的关注代码(例如缓存,事务感知,调用Web服务而不是进程内执行),或者此类依赖关系是否直接引用基础结构,因此将来可能会更改依赖关系整合点。
如果代码依赖于不需要控制来跨越逻辑/物理边界的东西,我或多或少都不会创建与这些边界交互的抽象。
我错过了什么吗?
答案 0 :(得分:6)
此外,在
时使用接口需要以特定方式对 执行多个对象,但这些对象并非基本相关。也许您的许多业务对象访问特定的实用程序对象,当他们这样做时,他们需要为该实用程序对象提供自己的引用,以便实用程序对象可以调用特定的方法。在接口中使用该方法并将该接口传递给该实用程序对象。
将接口作为参数传递在单元测试中非常有用。即使你只有一种类型的对象运行特定的接口,因此并不真正需要一个已定义的接口,你可以在单元测试中单独定义/实现一个接口“fake”。
,请查看Observer pattern和Dependency Injection。我不是说要实现这些模式,但它们说明了接口真正有用的地方类型。
另一个问题是实现了几个SOLID Principal,Open Closed principal和Interface Segregation principle。像前面的子弹一样,不要强调在任何地方严格执行这些原则(至少是马上),但是使用这些概念来帮助你将思维从哪些对象移到哪里转移到思考更多合同和依赖
最后,让我们不要太复杂:我们处于.NET中的强类型世界。如果您需要调用方法或设置属性,但是您传递/使用的对象可能根本不同,请使用接口。
我想补充一点,如果你的代码不会被另一个库引用(至少暂时一段时间),那么在特定情况下是否使用接口的决定是你可以他们负责任地推迟了。这些天,“提取界面”重构很容易。在我当前的项目中,我有一个对象被传递,我在想也许我应该切换到一个接口;我并没有强调它。
答案 1 :(得分:1)
进行单元测试时,接口抽象很方便。它有助于模拟测试对象。它在TDD中非常有用,无需实际使用数据库中的数据进行开发。
答案 2 :(得分:1)
如果您不需要在接口中找不到的类的任何功能...那么为什么不总是更喜欢接口实现呢?
它将使您的代码在将来更容易修改,更容易测试(模拟)。
答案 3 :(得分:1)
你已经有了正确的想法。我只会为此添加一些注释......
首先,抽象并不意味着'界面'。例如,“连接字符串”是一个抽象,即使它只是一个字符串...它不是关于所讨论事物的“类型”,而是关于该事物的使用意图。
其次,如果您正在进行任何类型的测试自动化,请查看通过编写测试而暴露的疼痛和摩擦。如果您发现自己必须为测试设置太多外部条件,则表明您需要在测试事项与其交互的事物之间进行更好的抽象。
答案 4 :(得分:1)
我觉得你说得很好。其中大部分都是风格化的东西。我看过有开源项目,其中所有东西都有接口和实现,这有点令人沮丧,但它可能会使迭代开发变得更容易,因为任何对象实现都可能会破坏,但虚拟变量仍然有效。但老实说,我可以通过继承来伪造任何不会过度使用final
关键字的类。
我会在你的列表中添加:任何可以被认为是黑盒子的东西都应该被抽象出来。这包括你提到的一些事情,但它也包括毛茸茸的算法,这些算法可能有多种有用的实现方式,对不同的情况有不同的优势。
此外,界面经常与复合对象派上用场。这是像java的swing库那样完成任务的唯一方法,但它对于更普通的对象也很有用。 (我个人喜欢像ValidityChecker
这样的界面,以及如何组成或组成从属ValidityChecker
的方式。)
答案 5 :(得分:0)
接口传递带来的大多数有用的东西都已经说过了。但是我想补充一下: