avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Noel J. Bergman" <n...@devtech.com>
Subject RE: reduction ad unum
Date Sat, 23 Nov 2002 21:17:17 GMT
Stephen,

Are we talking about the same thing?  Let's back up for a moment, and make
sure.  My note was in reply to Leo Sutic's note in which he reiterated Paul
Hammant's example of:

   contextualize (Context context) {
     ShutdownRequestingContext src =
       (ShutdownRequestingContext) context;
     src.requestShutdown();
   }

Leo said that it "looks good, but I really do not like the mass of castings
begin done."  He went on to give further examples (as had Paul), all in the
same vein: the Context implements multiple interfaces, and the
Contextualizable wants specific ones.  Leo gave an example where

I took Leo's objection and removed the need for the IS-A relationship.  The
caller provides the desired interface to the context, and the context
returns a reference to whatever will provide that interface within the
context:

   T t = (T) context.get(T.class);

thus changing the example to:

   contextualize (Context context) {
     ShutdownRequestingContext src =
       (ShutdownRequestingContext)
context.get(ShutdownRequestContext.class);
     src.requestShutdown();
   }

It doesn't remove the necessary cast, but it changes what the cast is
applied to, and that is very important.  For one thing, it decouples the
context object from the implementor of the requested interface.  This means
that deprecation and delegation are available, amongst other things.

But I expect that you should realize this because if you compare our two
solutions you will find that they are identical except in the parameter
encoding.  You have replaced the parameter in which I had placed the desired
Class (interface) with String (key):

   ShutdownRequestHandler handler =
     (ShutdownRequestHandler) context.get("shutdown-handler");
   handler.requestShutdown();

The key string is arbitrary, although it may be well-defined in a documented
list of keys.  But contrary to your claim that the "container ensures that
the entry value returned for the key 't' is castable to T", the context no
longer knows what type is expected by the caller.  Furthermore, classloader
issues may require the context to know the specific interface class that the
caller expects.

Perhaps this gets back to the issue Peter and Paul were debating in the
"Single Avalon Implementation" thread of whether contracts should be
expressed by interface or by well-defined key.  You didn't appear to
participate in that discussion, but it is what Paul was refering to in his
post to which Leo replied.  All I did was take Leo's specific objection and
attempt to fix it *within the context of that discussion.*

Unless there is a need for more than one "entry value" of type T within a
given context, and that you thus need a key to identify the entry other than
its type, then I believe that I've provided a workable interface that fully
decouples caller, context and service provider.  If there is a need for a
"key" then I believe it can be expressed as:

   T t = (T) context.get(T.class, "key");

Thoughts?

	--- Noel


--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message