I am writing my first "API jar" that will be open source library and used by (possibly) other developers. I've read Joshua Block's thesis on effective API design, and one of the things he talks about - that I never would have thought of otherwise - is his concepts of minimizing access and maximizing information hiding. Basically, you only want your API developers to have access to the Java objects they will be using, and you don't want your API developers to have access to any of the "guts" of your library.
In my several years as a Java developer, I've never had the need to make a class anything other than public
. Furthermore, I've never used nested classes either. So I'm sitting here wondering how do I implement this "information hiding" best practice in my Java API? And I think private, and possibly nested, classes is the answer. But where to begin?
.java
source file requires at least 1 public
class in it to compile. So for me to make a class private
(and non-nested), I need to "bundle it with a public
class. To me this makes sense only if the public
/private
classes are heavily related. But what if I have a section of my API that just consists of private
classes (for accessibility-minimizing-purposes) that don't relate to any other public
analogs?private
class nested, and when do you make it non-nested? Or is it just a matter of preference?Classes that are package-private (i.e. don't have any visibility modifier) are only visible by the classes of the same package. That's a way to make a class visible by several other classes of your API, but not by the outside world.
Nested private classes are also useful to make a non-public class, and their scope is even narrower: they're only visible by the enclosing class.
I suggest having a look at Guava's source code for an excellent API design. You'll see all kinds of techniques to hide internals to the outside there.
Personally, I don't believe in private
. I use protected
instead whenever feasible to allow for some of the major benefits of OO design.
Basically the 'information hiding' principle is not bad as a guideline. However, in practice one should not blindly follow it in all cases. - For the pure principle you would, as others suggested, need to define a set of interfaces as public and hide all the rest of your lib away with package-private classes, factory methods, and the like. Given that Java's package-private visibility has some issues that render it somewhat useless in many cases (- classes within your lib will want to cooperate across packages -) this in turn seems to prevent such an approach.
Besides, there are always at least two types of users of an API: the basic users, who will use the objects and methods you provide, and the users with complex requirements, who will want to modify the API's behavior (at least) by inheritance, which a lot of 'hidden' stuff will successfully prevent.
Don't be shy to make those things public
for which it may make sense, make things protected
which are not really needed to be public
, and make only those things private
which may cause harm if directly accessed by anything but their directly related code.
Another note: The hiding-principle has as a major purpose to simplify the use of your code by others and to imply and encourage the correct use thereof. But remember that documentation is another important means to achieve this; and documentation will be needed for a library anyway. - If you have 100 public methods and your docs state which 10 of those are needed for a use case the user of your lib will probably get along with that just as well as he would if only those 10 were visible to him.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With