[Zope3-dev] Context and Component Lookup

Jim Fulton jim at zope.com
Thu Aug 7 11:09:38 EDT 2003


I should point out, so that this doesn't drag on too long, that I'm going
to suggest an alternate proposal in a separate note that, I hope, will address both
of our concerns,


Phillip J. Eby wrote:
> At 05:23 PM 8/6/03 -0400, Jim Fulton wrote:
> 
>> Phillip J. Eby wrote:
>>
>> > just as a component that is "part of" a radio would expect to
>> > receive its "power" utility from the radio it is composed of.
>>
>> If I borrow my neighbor's DVD movie,
>> I'll play it with my DVD player and radio, even though it's still
>> their DVD. :)
> 
> 
> But you have now changed its context, in a way that I'd consider 
> equivalent to moving a content object. 

I disagree. The DVD still belongs to my friend.  The DVD simply
doesn't care what player plays it because the DVD and the player
interact through a standard interface.

> But, we were talking about
> *using* something.  To modify your analogy, I understand this to be more 
> like you going to your neighbor's house to watch the DVD on his player.  
> While you are there, you should respect the rules of *his* household - 
> i.e., context.

That's another example.

...

>> Maybe the difference is that my components are connected soley
>> through interfaces. Your connections tend to be more intimate.
>>
>> Generally, the dependencies are on interfaces that must be provided in
>> either case. So I don't see anything "reckless" here.
> 
> 
> And that makes it clearer that we aren't quite on the same page.  My 
> point was that if the "foreign" component does a utility lookup on 
> itself, and gets a different result based on who called it, that this 
> isn't a good idea. 

Right, I understand your point.  My point is that it shouldn't matter
because the interactions are through a common interface.

> 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.

> 
>> > If I need to
>>
>>> parameterize the component, why not just make an instance of it 
>>> that's attached to my environment, or else explicitly define 
>>> parameters as part of the call signature?
>>
>>
>> We're talking about sharing content components.  So we get a bit of 
>> content
>> from S2 that we want to use in S1.  We may need to adapt it to 
>> something else
>> we need. I see no harm in using our adapters.
> 
> 
> Me either!  What I am saying, though, is that if there's code in S1 that 
> does this, why can't the S1 code do so explicitly?  Here, S1 is the 
> consumer of the adapter, so it makes perfect sense for it to use S1 as 
> the lookup context.  What I don't want is for this to have any impact on 
> *the S2 code's execution*, which is what I understood you to be proposing.

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.

>> > It seems like an invitation to debugging hell to
>>
>>> have things controlled by some kind of threaded global.
>>
>>
>> And I've experienced debugging hell because objects didn't have the
>> context I expected them to have.  With what I propose, the source
>> of components is much easier to predict that the way things are now.
> 
> 
> And if the context is explicitly specified, it'll be even easier to 
> predict, right?  :)

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.

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

...

> I am saying there should be "freedom of choice" (objects that do lookups 
> can choose where they want to look up from) but no "invasion of privacy" 
> (other objects should not have the ability to reroute an object's 
> lookups, unless they are the object's owner or context, or have been 
> explicitly delegated this responsibility in some other way).

Fair enough,

...

> 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.

I'm willing to believe that some code does care and that code should
be able to exercise control over the lookup.


...


>> This is getting circular.  I don't want an object to need to be context
>> aware to find components. A component should be context aware if *it*
>> uses context itself in some way, as sometimes happens.  If component 
>> lookup
>> requires context, then any content component that might lookup components
>> must be context aware.  That's why I don't want component lookup to 
>> require
>> context.
> 
> 
> What I don't get, is why content components shouldn't be allowed to do a 
> context-free lookup in that case. 

They should be.

 > If the object doesn't have any
> context, then presumably its author *wanted* it that way. 

Yes, or, more likely, the author didn't care about 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.

...

>> If component lookup requires context, then context awareness is 
>> required to
>> do component lookup.
> 
> 
> This is the bit I don't get...  If somebody is *writing code to use the 
> Z3CA*, and they're writing a *persistent object*, they've already shown 
> themselves quite willing to join the Borg. 

I disagree very much.

- We don't require persistence.

- Persistence is used by many non-Zope applications.

- I certainly hope the component model will be useful for people outside of
   Zope.

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

...


> What I'm curious about here, is whether we differ over a style issue 
> here, or whether there are Z3 requirements that prevent you from using 
> the same approach.  It may just be a style issue, in that you've never 
> seemed particularly keen on encapsulation, while I on the other hand can 
> be incredibly persnickety about it.  :)

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.

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.

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.

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.

Jim

-- 
Jim Fulton           mailto:jim at zope.com       Python Powered!
CTO                  (703) 361-1714            http://www.python.org
Zope Corporation     http://www.zope.com       http://www.zope.org





More information about the Zope3-dev mailing list