DISCLAIMER: I'm not an authority on API design and I don't think there
are one-size-fits-all guidelines. I'm posting what works for me on my
current project.
IMHO each of the modifiers has it's place:
- when I create a class or interface, make it package-private unless it
is part of the package interface.
- when I want to expose a class outside a package, make it final,
unless it's designed for extension.
- avoid having classes designed for extension as it's too much effort
to design and document them.
So, at this point our class falls inside 3 categories - public class,
public final cllass, and package-private class.
- You *never* use protected in final classes.
- In package-private classes, protected is the same as package-private
access, still it's a matter of style - protected communicates better
that certain member is intended to be accessed from classes in the same
hirarchy. On the flip-side, there are no compiler checks to support
this, so I don't do it usually.
- The public non-final classes have to be specially designed for
extension, which also means that you cannot make any assumptions about
the caller. I find the checkstyle rule s good enough [1]. Also the XOM
project has very good API design guidelines [2].
- Protected non-final (PNF) methods imply that a method is intended to
be overriden and probably used by the base class (hook method). I'd say
avoid having non-empty or non-abstract PNF methods, as it complicates
the understanding - prime example is the Eclipse API. It's a good API,
but from reading other's people source, I figured that many programmers
repeat in their own method what was already done in the super-method.
Without detailed documentations on the pre/post conditions you are
bound to end with this. OTOH, if you do document the pre/post
conditions, this restricts the class evolution.
- Protected final - the method is utility method, intended to be called
by subclasses. Prime example are the JUnit assertions. Such methods
should have good descriptive names and reasonably good documentation.
In many cases you can go without them.
[1]
http://checkstyle.sourceforge.net/config_design.html#DesignForExtension
[2]
http://www.xom.nu/designprinciples.xhtml#d0e211