【问题标题】:Converting all parameters, return types, class definitions to use Interfaces转换所有参数、返回类型、类定义以使用接口
【发布时间】:2009-12-25 20:55:04
【问题描述】:

我正在将我的所有参数、返回类型、类转换为全部使用接口,即。 IUser 而不是 User。

除了维护它所需的额外代码之外,他们对这种方法有什么负面影响吗?

【问题讨论】:

    标签: c# oop interface


    【解决方案1】:

    这不是一种不常见的方法,尤其是在您进行大量嘲笑的情况下;但是,它存在以下问题:

    • 数据绑定支持(尤其是在向表中添加行时)
    • xml 序列化(包括 comms WCF、asmx 等),或一般基于契约的序列化

    您需要弄清楚模拟等的优势是否超过了这些问题。您可能在大多数情况下使用IUser,但(例如)在通信层使用原始 DTO 而不是接口可能更简单。

    请注意,我将上述内容应用于课程。如果您涉及结构,请记住,在大多数情况下,这也将涉及装箱。

    【讨论】:

    • +1 好点 - 我没想到数据绑定。至少在 WPF 中,这可以通过使用抽象基类而不是接口来缓解。但是,总的来说,我会说松散耦合的优势在于,它所涵盖的不仅仅是模拟,尽管它也包括模拟。
    【解决方案2】:

    总体而言,这将为您提供与松耦合相关的所有优势,所以总的来说,我认为这是一个巨大的胜利。不过,既然你问了缺点,我能想到的还有一些小缺点:

    • 涉及更多代码,因为您同时拥有接口声明和至少一个实现(您已经提到过这一点,所以为了完整起见,我将其包括在内)。
    • 它变得更加难以导航代码,因为您不能只转到定义来查看另一种方法的作用(尽管有人告诉我 Resharper 有助于这方面)。
    • 在某些情况下,合同中的内容可能不仅仅是语义,而接口无法捕捉到这一点。 BCL 中的经典示例是,如果您实现 IList,则必须在每次添加项目时增加 Count 属性。但是,界面中的任何内容都不会强迫您作为开发人员执行此操作。在这种情况下,可能值得考虑使用抽象基类。
    • 添加新成员方面,界面脆弱。再次,您可以consider abstract base classes instead

    【讨论】:

    • 完全同意你的第二点。我在代码库方面有过非常糟糕的经历,这些代码库有太多抽象,所有东西和它的狗都被抽象成一个接口。只是不可能知道发生了什么。 (雪上加霜的是,过度的抽象甚至没有提供松散耦合。接口不是松散耦合的神奇小精灵。)
    • 同意:松耦合需要接口,但不保证。
    【解决方案3】:

    我曾经经历过这个阶段,但在实践中发现,对于贫血的数据对象(即 POCO),不需要接口。

    在实践中,使用接口来定义行为契约可能很有用,但不一定要定义属性。

    一般来说,我建议您让单元测试指导您。如果您在整个应用程序中都有丰富的对象,那么您很可能需要接口。如果您有 POCO,您很可能只需要它们用于控制器样式的类。

    【讨论】:

      【解决方案4】:

      接口是非常好的东西,但是将它们应用于所有工件是大材小用的。特别是在java中,你最终会得到两个不同的文件(接口+实现)。所以(一如既往),这真的取决于:)

      关于“接口或非接口”

      • 我不会让域对象有接口(例如用户)。在我看来,代码理解相当混乱(对于域对象接口通常会定义 getter 方法)。最近,在适当的位置进行单元测试并拥有域对象接口是一件非常痛苦的事情。我必须模拟所有这些 getter,并且将测试数据放入域对象模拟中相当麻烦。
      • 粗粒度服务和 api 接口则相反。对他们来说,我从一开始就有一个界面。
      • 在更多内部模块封装的场景中,我开始时没有接口,并在必要时进行一些代码演变后做出反应并进行提取接口重构。

      接口工件名称的'I'前缀

      我以前也使用 Ixxx 前缀,但我(很高兴)现在摆脱了它,原因如下:

      • 很难在不断发展的代码库中保持所有这些“I”命名约定,尤其是在您进行大量重构时(提取接口、折叠接口等)
      • 对于客户端代码,无论类型是基于接口还是基于类,都应该是透明的
      • “我”会让你对好的接口和类名变得懒惰。

      【讨论】:

        【解决方案5】:

        与其说是缺点,不如说是一个警告。您会发现要实现良好的组件解耦,您需要使用依赖注入框架(也就是说,如果您想保持理智并了解您的接口映射到什么)。

        还容易发生的情况是,非平凡的类有时会自然地转换为多个接口。当您拥有公共静态方法(即User.CreateAdminUser)时尤其如此。您还会发现让界面保持状态并做事变得更加困难。界面通常是其中之一更自然。

        如果您在此过程中遇到困难,请花一点时间研究一下您尝试实施的合适范式。可能有人以前解决过这种特定的设计模式。考虑到这是一项大型的重构​​工作,您不妨多花点时间好好地完成它。

        【讨论】:

          【解决方案6】:

          避免使用ISuck 前缀。

          编辑ISuck 约定是应用于类型名称的Systems Hungarian 表示法的体现。

          【讨论】:

          • 今晚喝酒了吗?
          • .NET 开发人员希望接口以 I 开头,这是官方 .NET 命名约定的一部分。一个好的 API 是一个没有惊喜的 API,它的一切看起来和行为都像你预期的那样。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-30
          相关资源
          最近更新 更多