I am in the process of rearchitecting a fairly large legacy web application. Almost all of the classes in the old code base are public classes with the key classes containing mostly public (and sometimes static) methods. I am tasked to modularize this application for various obvious reasons in an evolutionary and progressive manner.

Java package names are used for various purposes such as:

  • Namespaces for tiers (web-tier, middle-tier, EIS-tier, etc.)
  • Namespaces for layers (service layer, DAO layer, etc.)
  • Namespaces for the purpose of the classes (Utility classes, implementation classes, etc.)
  • Namespaces based on module structure, deployment architecture, etc.

So, it is not always possible to put the implementation classes and the classes that need to access the implementation classes in the same package for any combination of the above reasons or use inheritance between them. So, the standard Java package-private and protected access specifiers might come up short.

So, one of the consequences of these restrictions in Java is to make the class public, eventhough you may not want this class accessible to every other class in that module/bundle or classpath by default (depending on whether you are talking about OSGi or non-OSGi based applications).

Sometimes, I miss the C++ “friend” Class (not the function) access specifier. However, I think the “friend” class in Java should not have access to all of the private members, instead it should have access to the “friend” or “protected” members of the other class. But, perhaps the designers of the Java language may have decided against this due to fear that the not-so-OO-developers might violate encapsulation by misusing this feature.

I have seen or heard of various approaches to solve this problem:

  • Use Delegation and/or Composition
  • Use “internal” package names
  • JavaDoc them as “for internal use only” (org.springframework.orm.hibernate3.SessionHolder in Spring API)
  • Use classloading trickery to simulate “friend” access specifier. This may not work in web applications or OSGi (due to the “modularity” or various classloading architectures))

My preferred way to do this (if I absolutely cannot put them all in the same package and make them package-private) is to use delegation or composition or a factory class (depending upon the type of situation that causes this problem).

What do you think? Are there better ways to do this?

Don’t we need a modified form of “friend” access specifier in Java?

Technorati Tags: , ,

TOP