[Zope3-dev] Re: ObjectHub/Event service: who sends those events anyway?

Steve Alexander steve@cat-box.net
Thu, 17 Oct 2002 12:30:42 +0000


> PROPOSAL:
> 
> For copy and paste, it seems to me that we can shuffle off the cookie or
> session tracking mechanism to the view code, so that the container
> itself might only need something like this:
> 
> class ICopyPasteContainer(IContainer):
>     def moveTo(key, destination): 
>         "move the item specified by key to the destination"
>     
>     def duplicateTo(key, destination):
>         "copy the item specified by key to the destination"

How can a container know how to duplicate things?
Does duplication happen at the ZODB level, or at the application level, 
or either, depending on some adapter?


> I also want a "link" in there but I won't scope creep here. ;-)
> 
> Then we would need the following modification for a folder that sends
> events:
> 
> class IVocalContainer(ICopyPasteContainer):
>     def setObject(key, object):
>         """sets object and sends an IObjectAdded event"""
>     
>     def silentSetObject(key, object):
>         """does not send an event; used by moveTo and duplicateTo"""
>     
>     def __delitem__(key):
>         """deletes object and sends an IObjectRemoved event"""
>     
>     def silentDel(key):
>         """does not send an event; used by moveTo"""
>     
>     def moveTo(key, destination, newkey=None):
>         "moves and sends an IObjectMoved event"""
>     
>     def duplicateTo(key, destination):
>         "duplicates and sends an IObjectDuplicated event"
>     
> Notice that's a new event type--IObjectDuplicated.  Presumably it would
> need a hub event parallel as well.
> 
> Then the folder handles all of the events for the contained objects
> except for IModified.  I think one possible ObjectHub subscriber might
> reject any moves that tried to move a registered object into a
> non-IVocalContainer, for instance.

Not really.

Containers don't need to know about events. Content classes don't need 
to know about events.

There is a separate class of components, which you might call 
"Management Components", that mediate between something that wants to 
manipulate a component, and the component itself.

For example, consider a glass of water:

   class IViewGlassOfWater(Interface):
       def getVolumeOfWater():
           'returns the volume of water in the glass in ml'

   class IChangeGlassOfWater(Interface):
       def drink(volume):
           'drinks the given volume of water'

       def fill(volume):
           'adds the volume of water to the glass'

   class IGlassOfWater(IViewGlassOfWater, IChangeGlassOfWater):
       pass

I would have a Content Component that implements IGlassOfWater:

   class GlassOfWater(Persistent):

     __implements__ = IGlassOfWater

     def __init__(self):
         self.__volume = 0

     def getVolumeOfWater(self):
         return self.__volume

     def drink(self, volume):
         if volume > self.__volume or volume < 0:
             raise ValueError, volume
         self.__volume -= volume

     def fill(self, volume):
         if volume < 0:
             raise ValueError, volume
         self.__volume += volume


Then, I would also have an interface for managing an IGlassOfWater:

   class IManageGlassOfWater(IChangeGlassOfWater):
       pass

I write this class, and register is as an adapter of IGlassOfWater:

   class ManageGlassOfWater:

     __implements__ = IManageGlassOfWater
     __used_for__ = IChangeGlassOfWater

     def __init__(self, glassOfWater):
         self.__glassOfWater = glassOfWater

     def drink(self, volume):
         # send out an IAboutToDrinkEvent
         self.__glassOfWater.drink(volume)

     def fill(self, volume):
         self.__glassOfWater.fill(volume)
         # send out an IJustFilledAGlassWithSomeWater event

When I have an IGlassOfWater, and I want to drink or fill it, I don't 
call the methods directly on the instance. Instead, I call them on 
getAdapter(myGlass).


I might have some details a bit wrong here, but I think the general idea 
is sound. I believe Jim was working on a step of the Tutorial with 
something like this in it.

--
Steve Alexander