接口应该放在一个单独的包中吗?

kct*_*ang 73 java packages interface

我是一个从事一个相当大的项目的团队的新手,拥有大量的组件和依赖项.对于每个组件,都有一个interfaces包放置了该组件的公开接口.这是一个好习惯吗?

我通常的做法一直是接口和实现在同一个包中.

coo*_*ird 91

放置接口和实现是很常见的,并且似乎不是问题.

以Java API为例 - 大多数类都将接口及其实现包含在同一个包中.

java.util包裹为例:

它包含的接口,如Set,Map,List,同时还具有实现,如HashSet,HashMapArrayList.

此外,Javadocs设计为在这些条件下运行良好,因为它在显示包的内容时将文档分离为InterfacesClasses视图.

除非有大量的接口,否则只有接口的包可能实际上有点过分.但是为了这样做而将接口分离到自己的包中听起来像是不好的做法.

如果需要将接口名称与实现区分开来,可以使用命名约定来使接口更易于识别:

  • 用一个前缀添加接口名称I.这种方法与.NET框架中的接口一起使用.告诉它IList是一个列表的接口是相当容易的.

  • 使用 - able后缀.这种方法是Java API中经常看到,比如Comparable,IterableSerializable仅举几例.

  • 虽然我不推荐使用I*命名约定,除非你在.NETverse中,否则只是为了保持一致性 (39认同)
  • 我在java代码中使用了这个约定,我发现它很有用.... YMMV (6认同)
  • 我知道这有点旧,但我现在发现的建议是清楚地命名界面,并将实现命名为strager.例如Interface = Store Implementation = StoreImpl主要是为了强调应该在实现上使用接口. (5认同)
  • 我同意关于接口不使用“I”前缀的评论,就像我不建议在实现中使用“impl”后缀一样,这是一篇很好的文章,反映了这些情况:https://octoperf.com /blog/2016/10/27/impl-classes-are-evil/ (2认同)

Cur*_*son 18

对于任何语言,将它们放在同一个包中都可以.重要的是暴露在外面的世界,以及它从外面看起来如何.没有人会知道或关心实施是否在同一个包中.

我们来看看这个特定的例子.

如果一个包中包含所有公共内容,而另一个包中的私有内容未公开,则库的客户端会看到一个包.如果您将私有内容移动到包含公开内容的包,但不要将它们从包中公开,则客户端会看到完全相同的内容.

因此,这有一个规则的气味,没有充分的理由:它根据公开可见的事情作出决定,而不会对公开可见的事物产生任何影响.

也就是说,如果在任何特定情况下将接口和实现拆分为单独的包似乎是个好主意,那么就这样做吧.我想到这样做的原因是包很大,或者你有一个替代实现,你可能想要链接而不是标准的.


jav*_*y79 10

在许多框架中,例如OSGi,你几乎必须这样做.我认为这会促进更松散的耦合,而不是jar级别.


Cam*_*ope 7

将接口放在不同包中的一个理由是,创建可以分发给产品或服务的消费者的"api"罐子更容易.完全可以将接口和实现一起完成,但如果它们位于不同的包中则更容易编写脚本.

  • 您可以将API项目分开(作为单独的可分发),但仍然不会阻止接口和实现在同一个包中.有点像你在与测试类相同的包中进行单元测试,但仍然在单独的构建工件中.Jars和包在Java中非常正交. (6认同)

Ken*_*nci 6

这本书实用软件工程:案例研究的办法,提倡把界面中单独的项目/包.

本书讨论的PCMEF +架构具有以下原则:

  1. 向下依赖原则(DDP)
  2. 向上通知原则(UNP)
  3. 邻居通信原理(NCP)
  4. 显式关联原则(EAP)
  5. 循环消除原则(CEP)
  6. 类命名原则(CNP)
  7. 熟人套餐原则(APP)

原则#3和#7的描述解释了为什么它是一个好主意:

邻居通信原则要求包只能与其邻居包直接通信.该原理确保系统不会分解为不可压缩的相互通信对象网络.为了强制执行此原则,非相邻对象之间的消息传递使用委派(第9.1.5.1节).在更复杂的场景中,熟人包(第9.1.8.2节)可用于对接口进行分组,以协助进行远程包的协作.

熟人包原则是邻居通信原则的结果.熟人包由对象在方法调用的参数中传递而不是具体对象的接口组成.接口可以在任何PCMEF包中实现.这有效地允许非相邻包之间的通信,同时将依赖性管理集中到单个熟人包.第9.1.8.2节解释了对熟人程序包的需求,并在PCMEF上下文中再次讨论.

请参阅此链接:http://comp.mq.edu.au/books/pse/about_book/Ch9.pdf


Pau*_*ier 5

是的,这是一个很好的做法,因为它允许您在不发布特定实现的情况下发布接口。就是说,如果您不需要发布外部接口,则将接口定义放在与实现相同的程序包中就没有问题。

  • 不发布实现是完全不同的事情,可以通过将它们打包私有化来完成-不能通过将它们放在单独的软件包中来完成。没有非公共软件包之类的东西。 (5认同)
  • -1是,是。这使得不必要地难以找到实现并将分离在一起的事物变得困难。 (3认同)
  • 也许如果您正在为JCP定义接口,或者说这很有意义,但是如果您正在为项目生成这些接口的多个具体实现,那么将这些接口分别打包似乎是不必要的负担。 (2认同)
  • 无论如何,这并没有太大的负担... (2认同)