[Zope-dev] ZPatterns design questions

Phillip J. Eby pje@telecommunity.com
Wed, 04 Oct 2000 09:44:15 -0500


At 03:46 PM 10/3/00 -0700, John Eikenberry wrote:
>
>Ok, I'm feeling pretty stupid right now but I have to ask what you mean by
>"define the property sheets as part of your class"? Do you mean using
>something like this in the DataSkin subclass:
>
>def __init__(self,id):
>    self.DataSkin.__init__(self,id)
>    ps = self.propertysheets
>    ps.manage_addPropertySheet('CompanyData','CompanyData')
>    ps.get('CompanyData')._properties = (
>        {'id':'name', 'type':'string',  'mode':'w'},
>        ...
>        )

That'd be one way to do it, although it's not compatible with what I had in
mind.  (i.e., you'd have to write SheetProviders rather than using
AttributeProviders.)  I was actually suggesting that you create
pseudo-propertysheets by just providing methods that change a set of
related attributes on the object.  Such methods are a lot easier to use
than actual propertysheets.


>> up a single trigger that checks whether any of the attributes you want to
>> mirror have changed, and then fires that off to the SQL db.  It would
>
>By 'trigger' you are referring to a RuleAgent plugin? Hmm... I had briefly
>thought about this, but most of the discussions relating to interfacing to
>an external RDB seemed to indicate subclassing a SheetProvider was the best
>course of action. I'll have look into this (hadn't spent much time figuring
>out RuleAgents yet).

At one time, it was the best course of action because RuleAgents didn't
exist and couldn't be written.  Now, Generic providers and triggers (or
their SkinScript equivalents) are available and more convenient than
writing a SheetProvider from scratch.

I am actually becoming somewhat disillusioned with the original
propertysheets extensibility setup, in that as I've been designing and
building real apps with ZPatterns I've not as yet found them to be a useful
route to take.  Anything that you can do with a propertysheet can be as
easily done by providing an attribute that actually returns another
DataSkin representing that "sheet", and seems much more natural as an
interaction model at the application design level.  Instead of
"foo.propertysheets.get('CustomerProperties').whatever", you can say
"foo.asCustomer.whatever".  IMHO it would appear that the shortcut route to
property set integration in ZPatterns is not to design custom property
sheets, but instead to define interface names for your integration points.
And this is only in circumstances where you can't simply make a whitebox
specialist map things with virtual objects (per my recent post to Steve
about framework integration).

What's happened is that ever since the advent of the Generic
providers/triggers, and especially of SkinScript, things have gotten a lot
easier.  In my original envisioning of ZPatterns, I thought that
AttributeProviders and SheetProviders would end up being written for LDAP,
SQL, etc., and would be relatively specialized.  Under those circumstances,
the best way to do this would have been a propertysheet.  Now, I'm
beginning to wonder if I shouldn't go back and deprecate all those
references to sheet providers and such, leaving them in place purely for
WebDAV support.  Actually, what I should probably do is add a new
declaration to SkinScript that lets you declare a mapping from a
propertysheet name or namespace to an attribute on the base DataSkin.
Then, you could use the attribute mapping facilities to create
propertysheet objects of your own devising.  I'd probably also have to
provide a suitable base class for those propertysheet objects, based on
DataSkin and providing all the Zope standard methods for a property sheet.
I'll consider this for 0.4.3 (coming in a couple weeks or so) but more
likely it'll be an 0.4.4 or later.


>> actually be a bit easier to set up if you were using a ZClass, since you
>> could create the property sheets there by just adding "DataSkin Property
>> Sheet" objects to the ZClass.  But the basic principle would still apply.
>
>We've come to the conclusion that ZClasses really are more a hinderance
>than a help, trading functionality for shorter learning curve. With
>straight python code you get much more control and the ability to use
>conventional editors and tools (cvs), without losing anything besides a bit
>of time figuring things out (which is better in the long run anyways).

Ty and I use ZClasses because you can see your changes much more quickly
than if you have to restart Zope.  Basing your ZClasses on DataSkin makes
the limitations pretty much disappear, from our point of view, because we
never put any actual "implementation" code in our ZClasses: just domain
logic, property sheets and UI (DTML) methods.  All the actual mapping
to/from data storage is carried out in the appropriate Rack or Specialist,
neatly seperated.  Occasionally we need an ExternalMethod in either the
ZClass or the Specialist, but these are getting rarer as we find ways to
create method-like helper objects that can be added through the Zope UI to
accomplish common tasks.  In general, we prefer that Python written outside
of PythonMethods be re-usable for a variety of projects rather than a
one-up for a specific application.  YMMV.  :)