[Zope3-dev] Context and Component Lookup

Phillip J. Eby pje at telecommunity.com
Thu Aug 7 12:01:29 EDT 2003


At 10:09 AM 8/7/03 -0400, Jim Fulton wrote:
>Phillip J. Eby wrote:
>>For example, this forbids the "foreign" component
>>from caching the result of such a lookup between calls.
>
>IMO YAGNI.  Individual components shouldn't be doing this sort
>of caching.

I didn't mean caching in a general sense.  What if the object sets 
'self.foo = lookup(something)', and uses the foo attribute in future, 
because it wants to be sure it's using the *same* IFoo across some time period?


>I see the point you are making. You are saying that a bit of code (e.g. a
>method) should control where the search for components it looks up take
>place, rather than the client of that method.
>
>What if the method doesn't care?  In some cases, the method actually
>wants to use the callers context.

Then shouldn't it use one of its parameters, that is documented in the 
interface as being used for the lookups?  I'm saying that "doesn't care" 
isn't really an option, because if the method doesn't care, then its caller 
probably does.  It should be explicit, and it should be documented.  If the 
method doesn't want to guarantee what context it will use, that should be 
documented too.


>Context is explicitly specified now. The context we normally choose
>is the context of the thing being adapted. You are suggesting
>that the context should always be the thing doing the adapting.

For presentation-related adaptation, yes.  I'm also suggesting that it's 
the common or default case for non-presentation matters.


>What if the thing doing the adapting doesn't have a context?

IMO, having a context is just a "cost of doing business" with a placeful 
CA, and a very reasonable one under most circumstances.


>>Okay, let me see if I understand.  What you want, is that code that calls 
>>Z3CA functions like getAdapter, getUtility, etc. should not have to know 
>>what "context" to use.  Or, in other words, objects should be able to use 
>>the Borg's communication system without needing implants.  :)
>
>Yes, as long as the code doesn't care where the component comes from.

That's the bit I don't get; if they truly don't care, what's wrong with 
using the global context?


>>So, if you don't have context, use only global services.  Aren't most Z3 
>>services globally registered anyway?
>
>But that defeats local customizations.

So then you *do* care...



>I don't want to make context management to be a prerequisite for using the
>component model.

Fair enough.  I think that:

1. it *is* a prerequisite anyway, you're just making it implicit

2. it would be better to be explicit, just make it as painless as possible

3. If you have to have objects obtain a context implicitly, they should 
grab hold of that context once and only once, and keep the context 
thereafter, to minimize Heisenbugs.  That way, when something doesn't work 
the  way you intend, it will at least behave consistently over the 
remaining execution of the program.


>Oh come on. Encapsulation is provided through interfaces.  If a component
>claims to depend on an interface, but isn't willing to accept alternate
>components that implement the interface, then *there* is the encapsulation
>problem.
>   When we use the component architecture, it's because we *want*
>to be used with alternative components. All we depend on is the interface.

Interfaces by themselves are not sufficient.  You already demonstrated this 
by saying "but that defeats local customizations", and by your earlier 
thought about event services.  Sure, a component will *work* with the 
alternate implementation.  It just might not do what you wanted the system 
as a whole to do.


>For example, utilities are a lot like modules, except that they can be
>substituted. They are a means of indirection. If I really need a particular
>component, I should get it by some other means that component lookup.

It's not that the component wants a specific item, but that its 
owner/creator wanted it to use a particular item.  Let's say I plug a DSP 
chip into a circuit board.  Do I want it to go around processing any kind 
of signals in my circuit?  No, I want it to process the signals (utilities) 
I provide in its context for it to process.  The fact that it will happily 
process any signal I give it, is irrelevant to me as the circuit designer.

Note by the way, that as the circuit designer, I *must* be concerned with 
context.  Every component must go somewhere, and I must ensure that it has 
all its input needs met.  If I have a component that doesn't require any 
utilities, and therefore doesn't care about context, that is all well and 
good.  But if I have a component that *does* require utilities, yet has no 
pins for me to supply them on (no ability to be part of a context), what 
good is it?  You are suggesting that whenever I use the component, we 
should e.g. piggyback the power on the signal and smuggle it in.  IMO, this 
is only acceptable for services that are stateless, since the object can't 
count on its environment to remain consistent from one method invocation to 
the next.


>Having said that, I now understand and accept that you want an intermediate
>level of indirection, where you'll be willing to accept any component that
>implements the specified interface *and* comes from a particular source.

Actually, it's you who said this, in that you've said global lookups aren't 
acceptable for context-free components.  But I do agree with what you've 
just said.  :)


>In general, I suggest that components don't and shouldn't care what
>other components they get hooked up to as long as those components satisfy
>their contracts.

I agree.  But the *consumer* of the component, or creator of the larger 
work that contains the component, may very much care what suppliers are 
connected to that component, because they are constructing a larger thing 
with its own desired invariants.  The reason for components, then, to do 
lookups using their own context, is to allow their context to customize 
their behavior for the good of the larger system within which they are 
contained, by supplying appropriate implementations of the required interfaces.




More information about the Zope3-dev mailing list