4

Say I have 20 classes in my root package. I decided to organize the classes by creating 3 subpackages under the root package. Then I put 5 classes into each of the subpackages, leaving 5 classes at the root package (because they are top level classes). Now because I need to use classes in subpackages from the 5 classes in the root package, I end up making classes in subpackages public, while before subpackaging those classes only have within package exposure.

The above code organization is done with good guidances. The subpackaging is by feature instead of by layer. The interdependency before packages are minimized. But still, a lot of subpackage classes make sense to be accessed from a level higher.

Is there a good practice addressing this type of scenarios?

  • You mean you don't usually make your classes `public`?! – Justin Apr 09 '14 at 15:51
  • Right. So people cannot arbitrarily (incorrectly) use classes I do not intend to publicize. – Jeff Sebastian Apr 09 '14 at 15:53
  • I think that's good practice that not many people use. Limitations in the java packaging system force you to make classes public if you are just trying to organize them. I feel like the best guideline would be to preserve encapsulation as much as possible: if no user should have access to your class, make it private static in the class that uses it. If your library needs to share it, make it package protected as much as you can. Check out [Google Guava](https://code.google.com/p/guava-libraries/)'s source code for how they handle that. – Giovanni Botta Apr 09 '14 at 16:09
  • As Vivin pointed out, packages in Java address namespacing only. A package is not a module! There are interesting experiments to implement the cake pattern in Java 8 http://stackoverflow.com/questions/14248766/cake-pattern-with-java8-possible. But the conclusion is basically, it's not worth the trouble. – Oliver Jan Krylow Apr 09 '14 at 16:44

1 Answers1

2

Unfortunately not. The most you can have is package-level visibility by making it package-private (default access). You cannot have it so that a class is only visible to other classes within the same module. I think Project Jigsaw and JSR 294 will address this (in addition to other stuff), but you're probably not going to see it until Java 9.

Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295
  • Thanks for the answer Vivin! So before that happens, do you know of any workarounds without having to make subpackage classes public? Would having one 'facade' public class in the subpackage be sane at all (or it is a complete overstretch which does not really hide anything)? – Jeff Sebastian Apr 09 '14 at 16:04
  • At this point I think it might be overkill. However you can ensure that people can't extend your classes by making them `final`, and where possible, you can perhaps make the constructors `private` as well. – Vivin Paliath Apr 09 '14 at 17:22