Editor's note: Sometimes, the most interesting discussions begin when someone says, "This may be a stupid question, but ..." If the person asking the question has taken the time to think about the problem before asking, the question is often not stupid at all. Uncertainty points out an ambiguity in the specs, holes in the docs, or a search for how more experienced programmers might address a particular problem. From time to time, we will publish one of the "(Not So) Stupid Questions" we receive and invite our readers to answer the question in the feedback section.
Remember that new people are joining the Java community all the time and may be looking for help from those with more experience. Also, those who began with Java as their first language can benefit from those coming to the community with experience in other languages. As always, answer the questions with kindness. You are also welcome to submit your questions to
.
This may be a stupid question, but ... "I have no idea when to create a new package and what should go in it."
First thoughts:
I have recently joined an open source project where all of their classes are in one single package that is more of a namespace than anything else. My first impulse is to suggest that they organize the project into packages and subpackages, but how do you decide what goes where? I've looked around for documents online, but most talk about packaging for deployment modules. I've looked at the java and javax packages to try to figure out what the recommended practices are.
Once you move some classes around and package them, you have to change accessibility and you might introduce dependencies. How do you balance organizing your project against introducing possible dependencies between packages? Is there a magic number of classes in a package that is too small to warrant a package, or too large to be a single package?
This brings me to three questions:
1. When do I introduce a new package?
2. How do I decide whether or not the package is a sibling to an existing package or a subpackage? and
3. When should a class be moved from one package to another?
(Not So) Stupid Questions is where we feature the questions you want to ask, but aren't sure how.
Program by function; organise by layer.
2005-05-13 12:28:16 tackline
[Reply | View]
Looking at java.* and javax.* code is often helpful to pick up conventions. However, don't take it too literally. For instance package names vary as to whether they are plural (javax.xml.parsers vs javax.xml.transform). May early class that should have been immutable are instead mutable (java.util.Date, java.awt.Point, etc). The collection of types in java.util is incoherent (even in 5.0 Iterable strayed into java.lang by recent historical accident). Also a general purpose library will be different from specific application code.
The number of (outer) types in a package is not directly relevant (other than as affects poorly-considered class browser UIs). How many fields should a class have? Relative complexity of the different options is more important.
Classes are much more important as units of modularity than packages. Avoid using the default 'package private' access on fields, methods and constructors. Unless you are writing a public API don't be too worried about making classes public.
IMO too much is made of cyclic dependencies. Cyclic dependencies between layers is v. bad, but between peers I don't think you should overly worry. Partitioning into packages on the lines of layers seems to work well, and this should tend to make package dependencies acyclic anyway. Prefer to keep down the number of packages the average package depends on. OTOH, some higher-level packages will be facade-like giving a large dependency spread.
Package hierarchy is not important. However I prefer to give higher level packages shorted name. So, com.acme.KillerApp rather than com.acme.apps.killer.app.boot.Main. Common classes that form the language of your code can sit in a package at the same depth as the grunt-work.
If there's one thing I'd like to be taken away it's this: Whether packages or classes: program by function; organise by layer.
I usually use packages more to strcture the source hierachically. This is dangerous, since packages are not hierachically by design. This means access modifiers do not work in sub packages.
Therefore be carefull and dont introduce too many sub packages. This only works if you have no inheritance relationships.
Where the class should go has to be decided based on dependencies of the class.
If you have a large project it makes sense to draw or just keep in your mind the directed graph of dependencies among all the packages.
Package B depends on Package A if there is a class from Package B which uses a class from Package A. Draw an arrow from B to A.
Next. In java there is not a notion of subpackage. Subpackage is not logical concept but more physical. While there are de-facto requirements for logical structuring of the packages, the physical structuring is more the matter of taste. Here is what it all means.
Logical structuring requirements: the directed graph of package dependencies MUST NOT have loops.
Physical structuring (which I personally like): Build a "tree"-like structure where child packages or subpackages depend on their only parent. For instance both com.acme.a.child1 and com.acme.a.child2 depend on com.acme.a but not on each other.
Opinions on grouping options?
2005-05-06 10:08:16 hammer
[Reply | View]
In my experience, many projects have used package names primarily as a way to organize code, not to scope class visibility. There are normally two ways to do this:
By role: In an MVC architecture, all view classes would be in their own package, all model classes in their package, etc.
By function:In the same architecture, all class comprising a GUI components (views, models, and controller) would all be in the same package. Each component would have a separate package.
I don't have any strong feelings either way and am wondering:
Is using packages primarily to organize code rather than limit class accessibilty a good or bad thing? Which the better way to organize code? Are there any other ways?
Any thought?
Opinions on grouping options?
2005-05-11 14:20:10 jimothy
[Reply | View]
In my experience, the "by role" taxonomy is broken. I've seen too many projects with "servlet," "ejb," and "dao" packages, for instance, with dozens of largely unrelated classes. Meanwhile, the servlet is in a different package than the EJBs and DAOs it interoperates with. The result is a developer spends time hoping between cluttered packages.
Group by function: Put your servlets, EJBs, and DAOs (if you are so cursed to build a project consisting of servlets, EJBs, and DAOs, that is) the relate to, say, user registration, in a "registration" package, and those that relate to purchasing in a "purchasing" package.
People think in terms of function: We look for tires in the automative section, and basketballs in the sporting goods section. We wouldn't expect to find these unrelated items in the same section, such as the "things that are round" or "things that are made of rubber" sections. Let common sense be your guide!
My 2p worth...
2005-05-05 08:13:41 javakiddy
[Reply | View]
You should remember that Java's access modifiers make use of packages as their chief 'currency' to group classes and their access permissions. So one consideration must be how a set of classes within a 'subsystem' interact with one another, and what that subsystem's public interface should be.
If A needs to access something in B, but you'd rather not make that something public to the world, then this is a strong hint that A and B should probably live in the same package. This allows these two specific classes to interact, while keeping the functionality private (to that package - not private in the Java keyword sense).
There are no hard and fast rules on this, but one rule of thumb I tend to try to observe is that a subpackage should either compliment its 'parent' (in which case it does not depend on it) or build on it (in which case it does depend on it). But the parent shouldn't depend on its subpackages.
For example, I have a little Open Source project which provides a Java implementation of the YMSG protocol, all in one package. I also have a subpackage which provides extra support functionality - such as codecs to work with YMSG's rich text message formats, filters to block SPIM, etc. The network package can be used on its own, but the support (sub)package depends on classes in the network package. To me this is a healthy one way relationship. But if the network (parent) package started to depend on the support subpackage, then I'd begin to worry if I'd got things in the right place.
But like I say, there are no hard and fast rules I know of...
two initial points
2005-05-05 05:24:21 asjf
[Reply | View]
1) although i use the word subpackage, its important to point out that they aren't really subpackages - ie there are no scoping differences between naming a pair of packages (p.a,p.b) or (p.a,p.a.b)
2) using a tool to generate the dependency (ie reference) graph between classes often shows strongly connected areas which can be grouped together as a package. If you label the edges of the references with the number of times a class is referenced from another class, then often the edges labelled with numbers less than 3 shouldn't be there (as a very adhoc rule of thumb) and are worth inspecting