cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Stefano Mazzocchi <stef...@apache.org>
Subject Re: Interfaces vs. Abstract classes (was Re: DirectoryGenerator.java)
Date Thu, 25 May 2000 23:13:08 GMT
Jonathan Stimmel wrote:
> 
> On Wed, May 24, 2000 at 08:59:43PM +0200, Giacomo Pati wrote:
> 
> > The interface definition is made according to the design pattern in use.
> > The abstract class fills some commonly used method with code and/or
> > implements other interfaces as well (you know multiple inheritance from
> > abstract classes is not possible in java).
> 
> Sure, interfaces let you implement mutliple inheritance (actually, that's
> probably a misnomer, since you're not inheriting actual method calls),
> but is that necessarily a Good Thing(tm)? 

Multiple inheritance for interface is a Good Thing(tm) IMO, without
that, the use of PolyMorphism as design pattern would be extremely
reduced.

> Interfaces should be used for secondary relationships, not primary roles. 

Who said that?

Intefaces are the equivalent of protocols, while abstract classes are
the equivalent of half-implemented protocol stacks.

Should we base our relationship on half-implemented protocol stacks, or
on RFC that define what to do?

> Looking through
> O'Reilly's "Java in a Nutshell", I rarely see this kind of relationship
> (interface->abstract->xxx), and its mostly for truly abstract concepts
> or utilities (the collections classes, specifically).

Well, sorry, but this doesn't mean anything. I haven't read the book,
but I did read and write lots of hardcore Java code and I learned it the
hard way, bouncing back when hitting the wall at full speed.

Interfaces make the _real_ difference between other object oriented
languages where polymorphism wasn't included right into the language.
Luckily it is so for Java.

Know which one is my favorite Java class? java.lang.Serializable.

Go take a look... yes, it's empty. It's hard to find the case where an
empty interface is required... but when it is so, they are _so_
incredibly elegant.

Let's make an example: suppose you want to create a Cocoon2 component,
say a JDBC pool manager. So you start by:

 public interface PoolManager extends Component {

ok, cool, now Cocoon is able to see it's a component and you are able to
access it thru all the other components that required access to other
components.

Yes, because there are two types of classes:

 - Components -> are used by others
 - Composers -> need to use external components

Ok, now you decide you need, say, a logger in order to function (this is
not really the case since logging should be a system API and not a
component, but just as an example). So your pool is _both_ a component
and a composer... so you must tell Cocoon about this

 public interface PoolManager extends Component, Composer {

Cool, but I need Cocoon to pass me my configurations, so 

 public interface PoolManager extends Component, Composer, Configurable
{

Hmmm, but most pool managers need their own thread to manage the
connections so

 public interface PoolManager extends Component, Composer, Configurable,
Runnable {
   public Connection getConnection(Query query);
 }

Now you are left with an interface that has _lots_ of methods and you
need a way to simply the creation of this component.

So you create an abstract class that takes care of all the component
machinery and declares abstract only those methods that _need_ to be
overloaded when providing the actual component logic.

Well, it took me, Pierpaolo and Federico almost a year to come up with
such a design pattern for componentized frameworks (see the Avalon
project on java.apache.org) and if you think this is abusing of
interfaces, well, I _strongly_ disagree with you since your abstract
classes do almost nothing compared to the flexibility of these patterns.
 
> I realise that I'm the dissenting opinion here, and it's not really a
> battle worth fighting (feels like the start of coding-style holy war).

No, this is not a religious war: there are -evident- proofs of
functionality here.

> IMO, though, encouraging this methodology as the rule (rather than the
> exception) only serves to increase cocoon's complexity by encouraging
> objects to have many relationships to each other. 

It guarantees that components work well between each other. 

When you do dynamic loading of components you have to sacrifice
compilation strong-typing for something else. Creating a good
infrastructure of casting types is the only way we found to glue
together the system, expecially when developped by many different
individuals.

In fact, it has proven to be extremely scalable and easy to be adopted
by new developers (isn't it so, guys?)

> Maintenance is an
> important consideration for any project, but especially for a project
> that is still in an evolutionary phase. A future version (e.g. 2.5) can
> always add the interfaces back if it's discovered that they truly are
> needed (and, of course, they could always be removed later if I can
> prove that they're unecessary =).

It's _exactly_ the opposite: without a good type-casting framework, this
project is not going to reach a stable point due to problems between
components.

-- 
Stefano Mazzocchi      One must still have chaos in oneself to be
                          able to give birth to a dancing star.
<stefano@apache.org>                             Friedrich Nietzsche
--------------------------------------------------------------------
 Missed us in Orlando? Make it up with ApacheCON Europe in London!
------------------------- http://ApacheCon.Com ---------------------



Mime
View raw message