commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Carman" <ja...@carmanconsulting.com>
Subject RE: [proxy] Moving Proxy to Commons Proper
Date Thu, 20 Oct 2005 10:50:19 GMT
What would an abstract class buy us?  Suppose ProxyFactory were an abstract
class.  In the initial release, it would have some abstract methods to be
overridden in the subclasses.  Then, I might have some users who decide (for
some crazy reason) to extend ProxyFactory on their own.  They implement the
abstract methods and all is good.  Now, suppose that I need to add a method
to ProxyFactory in the future.  The added method can't be abstract or else
it would break the binary compatibility.  Therefore, we'd have to provide an
implementation of the new method.  We'd have a choice here.  We could throw
an UnsupportedOperationException which would make the method unusable, but
maintain binary compatibility.  Or, we could provide a default
implementation which would probably have to be reflection-based anyway to
avoid unnecessary required dependencies.  I don't really like adding
unusable methods to my abstract class, so I would rather provide the default
implementation.  Thus, any new methods would be reflection based.  Why don't
we just make the base class reflection based in the first place?  

Again, I'm new to this whole "maintaining binary compatibility" thing,
because thus far I have mostly worked on projects where I control the source
for the clients of the code that I write.  So, I can go back and fix what I
broke!  :-)  So, how do you guys usually go about this?  Do you provide the
default implementation in the base class or throw an exception?

The JDK must introduce problems with binary compatibility all the time.  One
example I can think of is the JDBC API, which is almost entirely
interface-based.  They add methods to that API somewhat frequently (the 1.4
release has new methods in ResultSet I know), it seems.  How do JDBC driver
vendors avoid that?  Do they have to release new versions of the drivers
that implement the new versions of the interfaces?  I would guess they have
to; I've just never run into a problem.

-----Original Message-----
From: Stephen Colebourne [mailto:scolebourne@btopenworld.com] 
Sent: Thursday, October 20, 2005 5:32 AM
To: Jakarta Commons Developers List
Subject: RE: [proxy] Moving Proxy to Commons Proper

Why can ProxyFactory not be an abstract class?

Stephen

--- James Carman <james@carmanconsulting.com> wrote:

> Robert,
> 
> How about this?  We provide a "default"
> implementation which just uses JDK
> proxies.  So, ReflectionProxyFactory would become
> ProxyFactory and
> JavassistProxyFactory and CglibProxyFactory would
> just extend/override it.
> That way, if we do add a method to ProxyFactory, the
> subclasses don't
> necessarily have to override it.  The
> implementations would just use
> reflection rather than a more advanced proxying
> technique.  ProxyFactory
> would actually be concrete and not abstract in that
> case.  Does that sound
> like it would work better?  Would that address your
> concerns with the binary
> compatibility?  
> 
> James
> 
> -----Original Message-----
> From: robert burrell donkin
> [mailto:robertburrelldonkin@blueyonder.co.uk] 
> Sent: Wednesday, October 19, 2005 6:18 PM
> To: Jakarta Commons Developers List
> Subject: Re: [proxy] Moving Proxy to Commons Proper
> 
> On Wed, 2005-10-19 at 16:35 +0200, Knut Wannheden
> wrote:
> > On 10/19/05, James Carman
> <james@carmanconsulting.com> wrote:
> > > > i would also like to reiterate stephen's
> warning: if you use
> interfaces,
> > > > be very sure that you are not going to need to
> change them in any
> > > > fashion. i would very strongly suggest
> implementing the key
> > > > ProxyFactory logical interface as an abstract
> class. this isn't bias
> (i
> > > > love interfaces when coding applications) but
> a hard lesson painfully
> > > > learnt.
> > >
> > > Robert,
> > >
> > > I understand the concerns here, but I am really
> torn between changing
> the
> > > API and leaving it like it is.  IMHO, it is
> *very* unlikely that a user
> of
> > > Commons Proxy is even going to implement
> ProxyFactory on their own.  If
> I
> > > had to ballpark it, I would be surprised if 1
> out of every 100 (I might
> even
> > > go 1000) people who use Commons Proxy implement
> ProxyFactory.  That's
> the
> > > whole point of using Commons Proxy in the first
> place.  You don't have
> to
> > > write the proxying logic yourself!  So, what is
> our target here?  Are we
> > > looking for 100% backward compatibility with
> *all* projects?  Or, are we
> > > happy with keeping something more like 90% or
> 95% of our users happy?
> Maybe
> > > we could tell them in the documentation that if
> they have a proxying
> > > technology that they wish Commons Proxy
> supported that they can submit a
> > > request to the mailing list or into Bugzilla for
> it and we can take care
> of
> > > it (of course, any code that gets us going would
> help).  As long as we
> > > decide between AOP Alliance vs. "rolling our
> own" interfaces, I'm pretty
> > > happy with the ProxyFactory interface.  Besides,
> there's really nothing
> you
> > > can't do with Invokers.  That's sort of the
> "common denominator."
> > >
> > 
> > In Eclipse APIs it is common practice that
> interfaces are never
> > changed -- hence new interfaces have to be added
> when new changes are
> > required -- and abstract classes are used where
> changes (in form of
> > new methods) are expected (see
> >
>
http://www.artima.com/lejava/articles/designprinciples.html).
> > 
> > As you say the Invokers are the "common
> denominator". So ProxyFactory
> > could be implemented as an abstract base class
> with the
> > createInvokerProxy() method declared as abstract
> and the other proxy
> > factory methods defined in terms of that. Concrete
> implementaions
> > would although do best in overriding these other
> methods for
> > performance reasons.
> > 
> > Although, as you say, there are probably not many
> users who will want
> > to implement this interface anyways. So maybe it's
> best left as it is.
> > 
> > I'm torn on this one. Any other thoughs?
> 
> there are certain pitfalls associated with deep
> libraries that are not
> commonly found elsewhere and are therefore not
> generally well known
> amongst other communities. (by deep libraries, i
> mean libraries that are
> used by libraries rather than applications.) these
> issues don't really
> effect applications or frameworks. 
> 
> we often talk about two different forms of
> compatibility: semantic and
> binary. binary compatibility is defined by the java
> language and
> concerns when one version of a class can be
> substitute for another.
> semantic compatibility means that existing uses
> don't break when one
> version of a class is substituted for another.
> 
> when developing a deep library, compatibility is big
> issue. since the
> library will be used by many other libraries and so
> indirectly by many,
> many applications, breaking compatibility means
> disrupting many users
> who were not aware that they even used your library.
> this will make you
> very personally unpopular. due to the number of end
> users who may be
> effected by changes in semantics, breaking semantic
> compatibility is
> quite a big deal. so, it's usually better to choose
> delegation and
> logical interfaces over subclassing frameworks.
> 
> breaking binary compatibility is a very big deal for
> deep libraries. by
> breaking binary compatibility, all users must be
> forced to choose to
> have only one version of the library on the
> classpath. if a user is
> building an application and require two libraries
> each of which depends
> on a different version of your library, this will
> cause them great pain
> resulting in great anger. 
> 
> the problem with interfaces is that adding methods
> breaks binary
> compatibility. 
> 
> some of the commmons components are amazingly widely
> distributed. proxy
> is just starting out but in a year or two, maybe
> it'll be relied upon by
> hundreds of open source libraries (as several of the
> deep commons
> libraries are). now, imagine having to justify
> yourself to all those
> downstream users who use those libraries why you
> needed to break binary
> compatibility: this kind of thing really trashes
> your reputation and the
> reputation of your component as well as upsetting
> all those downstream
> users who'd never even heard of your library before.
> 
> but, this choice is yours. this is just advice and
> not a condition :)
> 
> - robert
> 
> 
>
---------------------------------------------------------------------
> To unsubscribe, e-mail:
> commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail:
> commons-dev-help@jakarta.apache.org
> 
> 
=== message truncated ===


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message