I disagree on the use the interfaces.
The problem with abstract classes, is that any methods you provide
"know" something of the implementation, unless the methods are
implemented solely by calling other abstract methods (which is rarely
the case if the abstract class contains ANY private members).
Prime examples of the good use of interfaces are the model interfaces
in Swing. There are a large variety of implementations - many not
using the provided abstract base classes - yet the standard JList,
JTable etc. work with them all. We use custom model implementations
all of the time.
This is possible because the interfaces were designed very well. You
MUST completely understand the problem domain in abstract terms in
order to define proper interfaces.
If you design poor interfaces, you will have the problems cited.
IndexReader and IndexWriter should have been interfaces. If they
were, lots of the code would not have been structured as it was, and
many problems people had in producing "other" implementations could
have been avoided.
As for future expansion, it is improbable in most cases that adding
new abstract methods will work - if that is the case, they can easily
be added to a static utility class. If the API is really changing/
adding, it is easy to create 'interfaceV2 extends interfaceV1'. If
the code worked before, and you want to support backwards code
compatibility between versions, this is a fool proof way to
accomplish it.
On Mar 19, 2008, at 12:03 PM, Doug Cutting wrote:
Chris Hostetter wrote:
Committers tend to prefer abstract classes for extension points
because it makes it easier to support backwards compatibility in
the cases were we want to add methods to extendable APIs and the
"default" behavior for these new methods is simple (or obvious
delegation to existing methods) so that people who have writen
custom impls can upgrade easily without needing to invest time in
making changes.
Yes, this is a huge problem with interfaces. We struggle with it
in Hadoop, where interfaces were used extensively and keep us from
improving core APIs in much-needed ways. In the end we'll end up
replacing them with abstract classes in a new package.
But abstract classes can be harder to mock when doing mock
testing, and some developers would prefer interfaces that they can
implement with their existing classes -- i suspect these people
who would prefer interfaces are willing to invest the time to make
changes to their impls when upgrading lucene if the interfaces
were to change.
These problems seem more easily surmountable. It should be no
harder to implement a mock version of an abstract class than an
interface. And developers are not much burdened by being unable to
use a single class for many things.
Perhaps the solution is a middle ground: altering our APIs such
that all extension points we advertise have both an abstract base
class as well as an interface and all methods that take them as
arguments use the interface name. then we relax our backcompat
commitments such that we garuntee between minor releases that the
interfaces won't change unless the corrisponding abstract base
class changes to acocunt for it ... so if customers subclass the
base class their code will continue to work, but if they implement
the interface directly ignoring the base class they are on their
own to ensure their code compiles against future minor versions.
It will be hard to enforce this. Applications will implement the
interfaces and will be broken by changes to them and folks will
complain, generating lengthy, non-productive incompatibility
flamewars.
After 10 years of Java programming, I find that interfaces are
rarely worth the trouble they create. They're handy for single-
method things that never change, like Comparable, Runnable, and
Cloneable, but for any more complicated API that's part of an
evolving system they're usually a mistake.
Doug
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]