8

Assuming that A, B, C derive from AbstractBaseClass and they are all part of the same java project, are package structures of the form...

 package com.whatever.###
 AbstractBaseClass.java

 package com.whatever.###.###
 A.java
 B.java
 C.java

... generally preferred over package structures of the form...

 package com.whatever.###.###
 AbstractBaseClass.java
 A.java
 B.java
 C.java

?

... or are few people likely to care?

John Smith
  • 4,416
  • 7
  • 41
  • 56
  • 2
    I'd expect quite the opposite: that it's a good practice to keep the abstract skeleton class package-private in the same package with the implementations. – Louis Wasserman Feb 07 '13 at 18:12

5 Answers5

1

I wrote a rather complex application application that used the first example and here is how I justified the design. In my case there was a common interface related to pricing an underwriting case, but several vendors who could provide different web services that would fill in the actual data. This was the package structure

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

Then in my code I used the import to wire the engine I wanted. Like this:

import com.example.pricing.*;
import com.example.pricing.vendorB.*;

IPricingProvider provider = Engine.create();

The advantages for me were the ability to have complex and messy implementations for each vendor (two were rest based one was a Web Service using wsimport so there was a lot of generated Java files) and not make Eclipse auto-complete look like a total nightmare. Also it made it easier to hand over a single vendor to a different developer.

Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • 2
    I disagree with your answer, because for me it is a nightmare to use the same classnames in different packages. I would prefer the same package and different classnames. I would just package different implementation into different jars (if possible) and only incluude the actual used vendors jar. But I think it is like prefer chocolade over vanilla. – Christian Kuetbach Feb 07 '13 at 18:25
  • I guess it comes down to what mechanism you want to use to manage different implementations. With things like well written Ant Build files, or Maven your approach likely wouldn't be easy more burdensome and would in fact result in tighter run times and easier deploys. Maybe It's time for me to back away from vanilla and give chocolate a try (+1 for the perspective) – Jason Sperske Feb 07 '13 at 18:45
1

It's actually generally good practice. Too many packages can get confusing very quickly. Keeping the implementation classes in the same package avoids an extra import statement and makes it easy to get to find your abstract class as the application codebase grows. The exception to this would be in cases where you have larger groups of implementing classes that all extend from abstract classes. So for example if you have a MySQL implementation and a Mongo implementation of a number of abstract clases you might want to put those in separate sub-packages. Something like

com.foo.data  <--- abstract classes
com.foo.data.mysql  <-- impl
com.foo.data.mongo  <-- impl
Rick Mangi
  • 3,761
  • 1
  • 14
  • 17
1

I think it depends on which of the parts is the more important one to the clients: the super class or the subclasses?

The latter is often the case when you think first of the subclasses, and just refactored out some common parts into a super class. Then this super class should be in the same package, and not visible publicly, like Louis said in his comment. If clients need to see the types of the subclasses, then you tend to have this pattern.

However, when you abstract away from the implementations and clients usually work only with the super class like in Jason's answer, then you should follow the strategy of putting each subclass into it's own package. Often these subclasses need further classes that are not of relevance to outside code, so an own package for them is a good thing.

Philipp Wendler
  • 11,184
  • 7
  • 52
  • 87
0

The package structure serves two purposes that are sometimes at odds.

  1. Make it easy for people learning your APIs and code to find the class that does what they want. In this case, you want to group like things together and use package names that make it obvious to someone browsing the Javadoc where to look. This argues for a small number of packages with broad divisions that are meaningful to API clients.
  2. Allow classes to access one another's package-private APIs. This argues for many small groups of closely coupled classes.

Large scale organization like packages should not depend on the current implementation details so I much prefer (1) over (2).

Deep hierarchies are hard to learn, so if adding a name element doesn't make learning your API easier, and doesn't help people filter out the bits that aren't relevant to their current tasks, then leave it out.

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
0

Surprisingly the answer is. It depends.

If you were going to do two sibling descendants, then one file for each (as in three,) makes sense. If they were small and/or you would lamost always be using both, (e.g. Directory and File), then there's a pragmatic argument for keeping them all in one anyway.

If you are constructing some deep inheritance hierarchy where only the final descendant has useable functionality (the more abstract a class is, the less it does), then putting it in a separate file is pointless.

Tony Hopkinson
  • 20,172
  • 3
  • 31
  • 39