Hello, I would like some thoughts on design strategies for Zope classes. I am developing a site that will require writing some custom classes. I would appreciate any opinions anyone could offer. I apologize for such a long message. My class will have some instance variables along with some standard Zope subobjects. My principal concern is that, because the graphical design of the site is still in development, I will probably be making lots of changes to the user interface of the class. I will want those changes to be propogated to existing instances of the class. The underlying logic, however, should be fairly stable. I've thought of three ways to develop the class: 1. Develop the entire class as a Zope product in Python. The advantage I see here is that developing the application logic is fairly straightforward with Python. I see problems, though, with the user interface, especially if I want to make changes to it after instantiating a few objects. It is my understanding that objects created from a Product are not automatically updated when changes are made to the class methods (as opposed to ZClasses, where they are). Am I correct here? 2. Develop the entire class as a ZClass The principal advantage I see is that changes to the class methods are dynamically updated in all instances of that ZClass. The problem is that DTML is (for me, at least) a pain in the ass to write any complicated application logic with. 3. Develop the application logic as a Product in Python, then use that class as a mix-in class for a ZClass that implements UI logic with dtml methods. This seems to be the best solution (even if it is the most work). I should get the advantage of having ZClass instances automatically update changes to ZClass methods, while having the programability of Python for application logic in the Product. If I do take this route, are there any quirks I should be aware of when inheriting a ZClass from a product? I am new to Zope and would appreciate any insight into the tradeoffs among these three strategies. Thank you, Garrin
On Fri, 16 Jun 2000, Garrin Kimmell wrote:
Hello,
[snip]
I've thought of three ways to develop the class:
1. Develop the entire class as a Zope product in Python.
The advantage I see here is that developing the application logic is fairly straightforward with Python. I see problems, though, with the user interface, especially if I want to make changes to it after instantiating a few objects. It is my understanding that objects created from a Product are not automatically updated when changes are made to the class methods (as opposed to ZClasses, where they are). Am I correct here?
The user interface for a Python Product is generally specified in .dtml files distributed with the Product. If you change one of these .dtml files, all you have to do is restart Zope and you will see the changes. Whether you have created one instance, or one hundred instances, they will all change their interface. What will *not* change (without a little help from you, described below) are the attributes that have been added or removed from the class. In this case, new instances will be configured with the new attributes, while old, previously instantiated instances will retain their old attribute configuration. To migrate your existing instances to the new configuration, you need to write a __setstate__() method in your class, for example (untested): class MyPersistentClass(Persistent): def __setstate__(self): Persistent.__setstate__(self, state) if not hasattr(self, 'newAttr'): self.newAttr = newValue if hasattr(self, 'deprecatedAttr'): del self.deprecatedAttr Each time the object's state is loaded from the ZODB, this method will be invoked. If a previously instantiated instance of your object is loaded, and does not contain an attribute called newAttr, it will be created. Likewise, if it contains an attribute called deprecatedAttr, it will be removed. ZClasses provide no such facility. You cannot upgrade ZClass instance attributes automatically, as far as I know. You'd have to write a script to go through your ZODB and upgrade the old instances manually. Boo.
2. Develop the entire class as a ZClass
The principal advantage I see is that changes to the class methods are dynamically updated in all instances of that ZClass. The problem is that DTML is (for me, at least) a pain in the ass to write any complicated application logic with.
As explained above, this advantage is shared by Python Products also. You do *not* want to write application logic with DTML. At a minimum, use Python Methods. Otherwise, use Python.
3. Develop the application logic as a Product in Python, then use that class as a mix-in class for a ZClass that implements UI logic with dtml methods.
This seems to be the best solution (even if it is the most work). I should get the advantage of having ZClass instances automatically update changes to ZClass methods, while having the programability of Python for application logic in the Product. If I do take this route, are there any quirks I should be aware of when inheriting a ZClass from a product?
This is a good way to go, and provides a nice advantage over vanilla Python Products: You do not have to restart Zope to see changes to your UI. However, you cannot reparent a ZClass after it has been created. Well, you can, but no one is very happy with the ways you have to do it. So, if you are a fly by the seat of your pants kind of coder, don't do it. If you do all of your analysis up front, and will know in advance exactly which classes your ZClass will inherit from, go for it. But, should you miss something in your analysis, you will have to reparent your ZClass and endure the pain involved with that process.
I am new to Zope and would appreciate any insight into the tradeoffs among these three strategies.
In summation, Python Products are, by far, the most flexible solution. You can upgrade them. You can write all of your logic in Python. You write your UI in DTML. You can manage all of this using CVS (or the version control system of your choice). Good stuff. Using ZClasses for your UI can allow you to see updates to your UI in realtime without having to restart Zope. In addition, ZClasses make your UI accessible to people who do not have access to the filesystem of your Zope server. You cannot easily use CVS with ZClasses, since they are stored in the ZODB and not the filesystem. Hope this helps!
Thank you, Garrin
--Jeff --- Jeff K. Hoffman 704.849.0731 x108 Chief Technology Officer mailto:jeff.hoffman@goingv.com Going Virtual, L.L.C. http://www.goingv.com/
Jeff wrote: ~ As explained above, this advantage is shared by Python Products also. You ~ do *not* want to write application logic with DTML. At a minimum, use ~ Python Methods. Otherwise, use Python. ~ Let me apologize in advance because i think this is going to turn out to be a really stupid question. I'm never gonna know the answer if i don't ask it though. :-\ I've seen this mentioned a lot (advice not to write application logic in DTML). If one wants to use pure python (and not Products and not external methods) to create complex actions/relationships, then where does one place this code? Obviously i can litter my DTML with python expressions, but this seems to be what is being recommended against strongly. Is there a way to use python "correctly" without writing a product and without encapsulating it in an external method? tesmia, ~c
On Fri, 16 Jun 2000, Charlie Derr wrote:
Jeff wrote:
~ As explained above, this advantage is shared by Python Products also. You ~ do *not* want to write application logic with DTML. At a minimum, use ~ Python Methods. Otherwise, use Python. ~
Let me apologize in advance because i think this is going to turn out to be a really stupid question. I'm never gonna know the answer if i don't ask it though. :-\
I've seen this mentioned a lot (advice not to write application logic in DTML). If one wants to use pure python (and not Products and not external methods) to create complex actions/relationships, then where does one place this code? Obviously i can litter my DTML with python expressions, but this seems to be what is being recommended against strongly. Is there a way to use python "correctly" without writing a product and without encapsulating it in an external method?
You have two choices: 1) Use PythonMethods, found at: http://www.zope.org/Members/4am/PythonMethod These work like DTML Methods, only you write them in Python. They are relatively safe, also. 2) Create a base class in Python, register it with Zope as a ZClass Base, and specify it as a parent class to your ZClass. i.e.: FILE: TestBase.py ----------------- class TestBase: """My ZClass Base class.""" def __init__(self): self.foo = 'Foo' def getFoo(self): return self.foo def setFoo(self, value): self.foo = value def initialize(context): context.registerBaseClass(TestBase) FILE: __init__.py ----------------- import TestBase def initialize(context): TestBase.initialize(context) Put these two files in your lib/python/Products/TestBase directory. Then, restart your Zope. Now, add a new product called Test. Inside it, create a ZClass called 'Test' with a meta-type of 'Test'. Specify TestBase as the base class. Inside the Test ZClass, create a DTML Method called index_html. Give it the following contents: <dtml-var standard_html_header> <P> Initial foo: <dtml-var getFoo> </P> <P> <dtml-call expr="setFoo('Hello, world.') New foo: <dtml-var getFoo> </P> <dtml-var standard_html_footer> Create an instance of the Test ZClass, and view its index_html. Voila. Hope this helps,
tesmia, ~c
--Jeff --- Jeff K. Hoffman 704.849.0731 x108 Chief Technology Officer mailto:jeff.hoffman@goingv.com Going Virtual, L.L.C. http://www.goingv.com/
Hi !
I would like some thoughts on design strategies for Zope classes. I am developing a site that will require writing some custom classes. I would appreciate any opinions anyone could offer.
I have summed up the discussion for future reference here: http://zdp.zope.org/portals/developers/designstrategies http://zdp.zope.org/portals/developers/designstrategies/products http://zdp.zope.org/portals/developers/designstrategies/zclasses http://zdp.zope.org/portals/developers/designstrategies/mix Please add your comments, further links and suggestions for improvements right in the ZDP Portal. Best regards, Maik Röder -- Open Source is "about being able to work together with people you've never met, on projects that are in a constant state of flux, on a time schedule that would cause a hummingbird's head to spin." Paul Ferris, http://www.linuxplanet.com/linuxplanet/opinions/1593/1/
participants (5)
-
Charlie Derr -
Garrin Kimmell -
Jeff Hoffman -
Jeff K. Hoffman -
Maik Roeder