[Zope3-dev] Context and Component Lookup

Jim Fulton jim at zope.com
Thu Aug 7 15:26:50 EDT 2003


Martijn Faassen wrote:
> Jim Fulton wrote:
> 
>>Martijn Faassen wrote:
>>
>>>>Right, I understand your point.  My point is that it shouldn't matter
>>>>because the interactions are through a common interface.
>>>
>>>That doesn't make sense to me. I can have two views, A and B, which
>>>have the same interface and are associated with the same content
>>>object interface. But it certainly matters which view is shown.
>>
>>To whome does it matter?
> 
> 
> To the person looking at the view, for one. To the developer who has
> to figure out he has to supply this view all of a sudden in his
> own context, even though it's not part of his package, just in order to use
> some other component that happens to require that view (or adapter
> or whatnot).
> 
> Actually there's another problem; you don't know *which* components the
> object in another context may need; object A implementing IFoo may need
> adapters to interface IBar and IBaz, while object B implementing IFoo
> may very well need adapters to interface IQux instead. And if your
> context is going to passed to them, that context needs to know about all
> three adapters... Or am I missing something here?

This is a good example.  So lets's say we have site S1, and
a subsite of S1, S11.  We're in S1 and we reach down into S11 and grab A,
which needs and adapter to IBar that exists only in S11.  A can't
do it's job unless we provide it the environment it expects.

So, I think we have a number of choices:

- If the author of A knows it's needs are special, it can arrange
   for A to supply it's own own context when looking up the adapter
   it needs.  In this case, it takes the chance that it will not
   use an adapter available where it's used, but it may not care.

- If the author of A knows it has this need and that the need
   might or might not be filled where it's used, then it can
   first try to get the adapter using the context in which it's used,
   and uses it's own context if that doesn't work:

     a = queryAdapter(self, IBar)
     if a is None:
        a = getAdapter(self, IBar, context=self)

- If the author of A has documented what A's requirements are,
   then he might just decide that people who use A without providing
   what it needs deserve to lose.  This is the implest approach in
   many ways, although, of course, it has it's drawbacks.


>> I suggest that it is often not the code that looks
>>up the views that cares. The system designer cares.
> 
> 
> Yes, as a system designer I care that I don't have to satisfy a lot
> of criteria in my context just in order to use an object somewhere
> else. In my mind, that object has its own context.

So you and I discussed this in IRC.  So we have the hypothetical situation
that object C in S1 wants to use A. It wants to use A in such a way that
the default place that A will look for components is in S11.  I don't
have a good answer for this.  I have to admit that I'm somewhat skeptical
that this is a situation that will occur much, if at all, in practice.
I'm open to suggestions.

> 
>>>What if I have two interfaces that do some storage, one using a relational 
>>>backend and the other the ZODB? Exact same interfaces but I certainly don't
>>>want to switch from one to the other just like that.
>>
>>Why? What difference does it make. The client of those interfaces shouldn't
>>care.  If the client's do care, there's a problem with the interfaces.
> 
> 
> Does that mean storage needs to be explicit in the interface?

Only if the client cares about the storage.  It isn't not in the interface,
the client probably doesn't care. If it does care, the client should
be using a different interface.

 > If I'm telling
> 
> somewhere.fridge.store('cheese')
> 
> from my context, where I have a utility that implements IFridgeStorage
> using a ZODB backend, and then I go do this from some other context where
> the utility is supplied that uses a relational backend, I'll get
> confused, right?

Why would you get confused?  My family used to kave an old Kerosene refrigerator.
No I have an electric one. I didn't have any problem with thw switch. The interface
was the same. They both had doors and the stuff inside stayed cold.

> 
>>OTOH, parties assembling a system may care very much which components are
>>used, but these preferences are expressed in the site configuration, not
>>in the component code.
> 
> 
> So if you have:
> 
>   * site X which maintains state
> 
>   * The way the state is managed depends on component lookup
> 
>   * site Y and Z both supply different components which influence state
>      management in their own contexts.
> 
>   * site Y can now affect the state of site X in a way that may be invisible
>     to site Z, and vice versa.
> 
> I'd expect instead X to have its own context with components and that site
> Y and Z defer to this when dealing with X. Only if I move something from
> X to a different context will X's behavior be modified.

I'm sorry, I just didn't following that.  It's too general.  I can't
follow what the interactions are.

> Perhaps I'm just completely missing the point, but I see difficulty
> both with this, and with the requirement that I suddenly need to 
> supply a lot of components that my site doesn't directly deal with,
> just in order to use a different area of the system. 

Sometimes, it just doesn't pay to try to do this.  It may be, that I'll be
unable to use an object from another site if that object:

- Has things that it expects to have met by the using environment, and

- I can't meet those needs.

Sometimes, you just can't keep a wild animal as a pet. :)


> If I'm going to show a view for a content object that's in a different 
> folder which supplies its own views, I now have to supply those views myself in
> order to make things work.

Only if you use those views.

 > This seems odd to me; I should only have to do that
> if I'm going to use this content object in my own context, I thought.

I guess it really boils down to what you want to do.  If an object really
needs things that are only found in it's place, then it should supply an explicit
context when it looks things up.

I think that, in practice, this won't be such a problem.  Despite my original
proposal, I don't think there will be much sharing accross unrelated sites.
When sites are related, designers will arrange for the necessary components
to be in place for sharing to take place.

...

> I mean, naively thinking I think it should
> be possible to use (call a method on) an object without having to 
> worry about how this object interacts with other objects. I'd call
> this use.

Right, but somebody has to worry about it. Whoever introduced that component
into the system should have arranged for the other components it needed.

...


> Hm, I'm reasoning from the case where I, the author of components, also have
> an idea of how they're assembled. In fact, I may be actually writing
> an application, worrying about assemblages and so on.
> 
> I am also assuming that some other area of the application is created
> and assembled by someone else. Now I want to interact with this other
> area. There are multiple author/assemblers. 
> 
>>From the pure assembler point of view.. Imagine I have this assemblage
> of components. Now I want to hook up one component to another component
> which is in someone else's assemblage. In your model my context matters, so
> this would mean that I would need to replicate a version of this other
> assemblage in my own assembly before it all works. Is that a correct
> interpretation?

I suppose so. But if you are using the other assemblage, doesn't it already
have one it needs for it's own requirements? You'd be typically building a
single site by composing these and other assemblages.

...

> Imagine there's a site X, which contains objects. It somehow has a need
> for a count of those objects, and looks up a service which maintains this
> count.
> 
> Now I have a site Y, which uses facilities in site X by calling into
> it. I have to supply a version of the counting service in site X. But
> this version of the service won't have the correct count.

So you are accessing some facility that depends on the count.  So, let's
say the job of this facility is to generate a count report.  There are
2 possibilities:

1. The facility generates a count report for the place it's used.
    In that case, it will report Y's count and it's doing it's job.

2. The facility generates an "X count report". That is, it's job is
    to report specifically on the count in X. Well, in that case,
    the facility had better supply a specific context when it gets
    the count service so that it gets the right one.

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