假设A,B,C派生自AbstractBaseClass并且它们都是同一个java项目的一部分,那么表单的包结构......
package com.whatever.###
AbstractBaseClass.java
package com.whatever.###.###
A.java
B.java
C.java
...通常比形式的包装结构更受欢迎...
package com.whatever.###.###
AbstractBaseClass.java
A.java
B.java
C.java
......或者很少有人关心?
答案 0 :(得分:1)
我写了一个相当复杂的应用程序应用程序,它使用了第一个例子,这就是我如何证明设计的合理性。在我的案例中,有一个与承保案例定价相关的通用界面,但有几个供应商可以提供不同的Web服务来填写实际数据。这是包结构
com.example.pricing
\IPricingProvider.java
\AbstractPriceProvider.java
com.example.pricing.vendorA
\PricingEngine.java
com.example.pricing.vendorB
\PricingEngine.java
com.example.pricing.vendorC
\PricingEngine.java
然后在我的代码中,我使用import
连接我想要的引擎。像这样:
import com.example.pricing.*;
import com.example.pricing.vendorB.*;
IPricingProvider provider = Engine.create();
对我来说,优点是能够为每个供应商提供复杂而混乱的实现(其中两个是基于休息的,一个是使用wsimport
的Web服务,所以有很多生成的Java文件)而不是使Eclipse自动化 - 完全看起来像一场彻头彻尾的噩梦。此外,它还可以更轻松地将单个供应商交给不同的开发人员。
答案 1 :(得分:0)
这实际上是一种很好的做法。太多的包可能会很快混淆。将实现类保存在同一个包中可以避免额外的import语句,并且随着应用程序代码库的增长,可以轻松找到抽象类。例外情况是你有大量的实现类,这些类都是从抽象类扩展而来的。因此,例如,如果您有一个MySQL实现和许多抽象分支的Mongo实现,您可能希望将它们放在单独的子包中。像
这样的东西com.foo.data <--- abstract classes
com.foo.data.mysql <-- impl
com.foo.data.mongo <-- impl
答案 2 :(得分:0)
包结构有两个目的,有时是不一致的。
像包这样的大型组织不应该依赖于当前的实现细节,所以我更喜欢(1)而不是(2)。
深层次结构很难学习,因此如果添加名称元素不会使学习API更容易,并且无法帮助人们过滤掉与当前任务无关的位,那么请将其删除。
答案 3 :(得分:0)
我认为这取决于哪个部分对客户来说更重要:超类还是子类?
当您考虑第一个子类时,通常会出现这种情况,并且只是将一些常见部分重构为超类。然后这个超级类应该在同一个包中,并且不会公开显示,就像路易斯在评论中所说的那样。如果客户端需要查看子类的类型,那么您倾向于使用这种模式。
然而,当你从实现中抽象出来并且客户端通常只在Jason的答案中使用超类时,那么你应该遵循将每个子类放入它自己的包中的策略。通常这些子类需要更多与外部代码无关的类,因此对它们自己的包是一件好事。
答案 4 :(得分:0)
令人惊讶的答案是。这取决于。
如果你要做两个兄弟的后代,那么每个的一个文件(如三个)是有意义的。如果它们很小和/或你几乎总是同时使用它们(例如目录和文件),那么无论如何都有一个实用的论据可以将它们全部保存在一起。
如果要构建一些深层继承层次结构,其中只有最终的后代具有可用的功能(类越抽象,它就越少),那么将它放在一个单独的文件中是毫无意义的。