【问题标题】:In which package should the implementation of a Java interface reside?Java 接口的实现应该驻留在哪个包中?
【发布时间】:2012-10-10 04:20:19
【问题描述】:

假设我有一个接口:

package org.my.dicom.CEchoSCU;

public interface CEchoSCU {
    // stuff here...
}

我也会有一个接口的实现:

public class SimpleCEchoSCU implements CEchoSCU {
    // stuff here...
}

我的问题是,哪个包应该包含实现?我见过其他开发人员将实现与接口放在同一个包中(在这种情况下为org.my.dicom),以及使用单独包的情况(通常类似于org.my.dicom.impl)。除了个人喜好之外,还有什么理由比另一个更喜欢一个吗?

【问题讨论】:

  • 可以将实现类放在任意包中
  • 包和类中的“impl”是恕我直言,表明您没有在命名约定上付出任何努力。如此多的开发人员认为这被认为是可接受的约定,这是一种可悲的情况。对于它传达的所有信息,不妨将其称为“.actualclass”。

标签: java interface package


【解决方案1】:

我更喜欢将实现放在具有这样名称的包中:

path.to.package.of.interface.impl

但是,我不认为这是一个普遍的惯例,我猜这是开发软件的组织特有的。

【讨论】:

    【解决方案2】:

    包通常是一个偏好和组织问题。有些地方会使用构建脚本来过滤掉 API 接口,例如,如果它们位于实现的单独包中,这可能更容易做到。真的,我认为最重要的是保持一致,这样人们就知道会发生什么(除非您使用的工具或脚本会对您施加限制)。

    【讨论】:

      【解决方案3】:

      好吧,关于将implementation 课程和interface 放在哪里,这并不是一个硬性规定。您可以将它们放在任何包中,只要它们可以在应有的位置访问即可。

      但是,当然,您还希望将所有related classespackageclass(即not related)放在set of classes 中,放在different package 中。

      大多数时候,我的做法是:- 我将interfaces 保存在different package 中,将implementing classes 保存在different package 中。这样,如果我想将我的接口提供给其他人,那么我可以直接将包含我所有接口的包分发出去。

      不过,这完全取决于您的要求,以及您在代码中遵循的设计实践。

      所以我选择的包名一般是:-

      • com.someName.api -> 用于接口
      • com.someName.impl -> 用于实现类。

      这样我就可以轻松地将apiimplementation 分开。

      【讨论】:

        【解决方案4】:

        将实现类放在任何包中都没有错。不会有任何编译错误。但是,这取决于项目代码设置放置 impl 类的位置。在大多数情况下,实现类将与接口在同一个包中。

        但是接口可以由不同种类的类实现,所以在这种情况下,实现类和接口将在不同的包中。

        示例是一个接口Bounceable 可以由BallJelly 甚至Car 实现!

        【讨论】:

          【解决方案5】:

          一个类实现,除其他外,一个接口。我会将类放在与类的其余部分所做/包含的内容相关的包中,而不是反映它实现的一个接口的包中。例如,如果我有 200 个实现 Printable 的类,我不会将它们全部放在一个包 com.mycompany.impl.printable 中。实现 printable 的 Airplane 类将与其他飞机的东西放在一个包中。船类将与其他船的东西放在一个包中。实现 Printable 的 Car 类将与其他汽车内容放在一个包中。

          如果所有 SimpleCEchoSCU(以及任何其他未来类)都实现了 CEchoSCU,那么您应该考虑将 CEchoSCU 设为抽象基类并派生不同的实现。无论哪种方式,(接口或抽象基类)事物都是完全相关的,我会将它们放在同一个包中。

          【讨论】:

          • 不会完全同意抽象类 - 相同的接口不是考虑抽象类的理由。抽象类意味着继承,而继承意味着多个相同的接口,意味着第一级类型祖先相同。如果你明白我的意思。 Fish 和 Bird 可能具有相同的接口、移动、呼吸,但我认为通过继承进行任何功能代码重用是有风险的——它们的类型相差太大。尽管您可能希望它们的实现有很大差异才能进行代码重用。
          【解决方案6】:

          我通常遵循以下规则:

          • 如果你想提供通用的实现,把它们放在同一个 包(例如 List 和 ArrayList)
          • 如果您有可重用的实现,但例如对于不同的技术或不同的业务功能,将它们放在单独的包中
          • 如果您有私有实现(其他人不应直接实例化),请将它们放在 *.impl 或 *.internal 包中。这在 OSGi 包中很常见。

          【讨论】:

            猜你喜欢
            • 2012-06-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-04-26
            • 1970-01-01
            相关资源
            最近更新 更多