Core Java

Why you should control Visibility of Class and Interface in Java

One of the important aspects of software development is maintenance, and  it’s proven by experience that a piece of software which keeps visibility of its components low is more maintainable than one that exposes its components more. You won’t realize it upfront, but you will miss it badly, while redesigning your application. Since maintaining backwards compatibility is a “must have” requirement for many apps, you end up patching and repeating the same mistakes. You can not do much because lots of other applications are tightly integrated with your class and interfaces.

Java has always put encapsulation on priority, provided support of access modifiers from the very beginning. It provides three ways to control visibility of any Type e.g. class or interface, by making them public,package-private or private. What happened to protected, can’t we use protected with class or interface. No you can’t, you can only use two access modifier with types, protected is not a legal modifier for a class or an interface. Also a top level class (a class whose name is same as of Java source file which contains it)  can be either public or package private (without any access modifier), it can not be private.

Only a nested class can be private, public or package-private.  A public class is accessible to everyone, and it is most visible. Try to keep only key interfaces public, never let your implementation go public until you think it’s complete and mature. On the other hand, private Type is the least visible, and only nested class or interfaces can be private in Java. Since it’s the least visible, you have full control of this class to alter its behaviour with experiences, new technologies, tools and redesign. A clever midway is package-private visibility, which is also default visibility, there is no such keyword as package-private. Instead if you don’t provide any access modifier, then Java assumes that it is package-private, and subsequently makes it visible only on the same package. If your classes and interfaces are shared only between other classes in the same package, make them package-private. Since a client cannot access them, they are also relative safe to change.

How to control Visibility of Class or Interface in Java

Apart from reducing visibility of class or interface using access modifiers, there are a couple of other ways to do that, depending upon your runtime environment as well. At component level, such as in an Application Server like Websphere, Weblogic or JBoss, an implementation class can be proxied or wrapped to minimize external exposure. No matter what you do, there will always be some type, which needs to be exposed to external world, but with a proxy or wrapper, you can still manage them. Even though client programs, can load proxied implementation class, they will mostly get an immutable proxy or wrapper. For example getServletContext() from Java Servlet API (javax.servlet) returns an implementation of javax.servlet.ServletContext, which is usually an immutable proxy to fulfil promises made in ServletContext interface. It’s most likely that application server is running with different implementation of javax.servlet.ServletContext interface. Similar pattern can be used in the implementation of other externally exposed interfaces e.g. ServletRequest, ServletResponse, javax.ejb.EJBContext, javax.ejb.TimerService etc. Different application servers may use different implementations to support these global interfaces.

Visibility of Class and Interface in Java
Writing open source libraries is also a nice way to understand the need of controlling visibility of class and interface. Another interesting case is a component based Java application server e.g. JBoss, WebLogic or WebSphere. These servers provide low level services e.g. transaction management, security, persistence, object pooling etc. In short, a production system uses both application server’s code as well as application’s code to work perfectly. In order to be maintainable e.g. switching between different application servers, your app and server code should be loosely coupled and should maintain safe distance.  Application server’s internal implementation classes and interfaces should be completely hidden from the user applications for security purpose. If the application packages the same library that the server contains, care must be taken that the server does not inadvertently load the application’s version via thread context classloader.

JDK Example of Controlling Visibility of Java Class

One more interesting example of controlling visibility is my favourite EnumSet class. Java designers made it an abstract class to avoid instantiation, and provided factory methods as only way to create instance of that class e.g. EnumSet.of() or EnumSet.noneOf() methods. Internally they have two separate implementation in form of RegularEnumSet and JumboEnumSet, which is automatically chosen by static factory methods depending upon size of key universe. For example, if the number of values in a given Enum is less than 64, then RegularEnumSet is used, otherwise an instance of JumboEnumSet is returned. The beauty of this design is that, both of these implementations are package-private, which means that clients have no idea about them. They are completely transparent to users and there is additional security enforced by making these class abstract, because you cannot create an instance of an abstract class. This not only allows you to choose the most appropriate implementation, but also it would be very easy to replace them with a newer and better implementation. Though they are a really special class, and RegularEnumSet uses a long value to store enum constants. IMHO, this is a fantastic example of controlling visibility of classes from the JDK itself.

In short, by minimizing visibility, which also leverages the benefit of Encapsulation, a well encapsulated code is more secure and maintainable. With the pace of technology, whatever you write today, becomes outdated in couple of years, so following basic principles of class design can help you get most from updated tools, libraries and JDK implementation.

Javin Paul

I have been working in Java, FIX Tutorial and Tibco RV messaging technology from past 7 years. I am interested in writing and meeting people, reading and learning about new subjects.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button