Discussion:
[Pyogp] Explaining the Zope Component Architecture Part 1: Interfaces
Christian Scholz
2008-07-13 17:42:15 UTC
Permalink
As I am planning to write some tutorial in some parts I thought I can
start here as well and write it down, get some feedback and incorporate
this into a better version.

So let's start with the reasons for the Zope Component Architecture.

The main one is I think the breakdown into easier to manage components.
In Zope2 we e.g. had lots of functionality in classes but those classes
were huge and not understandable anymore. Moreover we had mixin classes
which provided functionality which could be shared among different classes.

Like here is the definition of the Item class in Zope2:

class Item(Base, Resource, CopySource, App.Management.Tabs, Traversable,
ZDOM.Element,
AccessControl.Owned.Owned,
App.Undo.UndoSupport,
):

Derived from that was SimpleItem (which actually made it not simpler but
worse):

class SimpleItem(Item, Globals.Persistent,
Acquisition.Implicit,
AccessControl.Role.RoleManager,
):

So the danger here is that even with new frameworks it can happen that
things grow too big. Many times some functionality is needed for a group
of classes (like in this case e.g. the AccessControl stuff) so that it
becomes a mixin class.

In Zope3 the concept of interfaces was introduced to handle such
functionality instead. Interfaces are the basic building block for the
whole Zope Component Architecture on which the actual application server
Zope is built (but it's not used in pyogp, just the component idea).

Now for an ongoing example for this tutorial imagine a simple content
management system where we have a simple document type which has a title
and a body (text).

class Document(object):

def __init__(self, title="",body=""):
self.title =title
self.body = body

def render(self):
"""render the body"""
return """<html>
<head>
<title>%s</title>
</head>
<body<
<h1>%s</h1>
<p />
%s
</body>
</html>
""" %(self.title,self.title,self.body)

This is a very small example which can render a title and a body in a
fixed HTML template.

Now to make this more flexible we can start with marking those elements
as public which should be like that:

from zope.interface import Attributes, Interface
class IDocument(Interface):
"""a document"""
title = Attributes("""the title of the document""")
body = Attributes("""the body of the document""")

def render():
"""render the document"""

This is all we need. Note that the method here does not contain the self
parameter. This is usually omitted in interface definitions. We can use
this interface class also to document our Document type. We can also add
private methods to the Document class itself but only those in the
interface should be used.

To mark the Document class itself as implementing this interface we write:

from zope.interface import implements
class Document(object):
implements(IDocument)

def __init__(self, ...)
...

This does not mean that the compliance of the interface is checked on
runtime but it can be done inside a unit test which sometimes make sense
to see if you did not forget to implement something.

For a user of your class it now makes sense to first look at all the
interfaces defined to get a quick overview of which methods and
attributes your class has. He then knows what he can do with it. The
next step would be to look at unit or doc tests.

Generally it is a good idea to start with sketching out your interface
definition (even better to start with a doctest and then derive the
interface of your imagined components from that). You can see then quite
early if it makes sense or not.

Usually we also put interface definitions in interfaces.py or we make a
folder interfaces/ and put them inside in logical block (if you plan to
have many interfaces).

Now that we've seen how to define interfaces the question is how we
actually use them as so far they only maybe help us to think differently
about our project (which IMHO is still a big win IMHO).

This will be described in the upcoming parts.
--
Christian Scholz video blog: http://comlounge.tv
COM.lounge blog: http://mrtopf.de/blog
Luetticher Strasse 10 Skype: HerrTopf
52064 Aachen Homepage: http://comlounge.net
Tel: +49 241 400 730 0 E-Mail ***@comlounge.net
Fax: +49 241 979 00 850 IRC: MrTopf, Tao_T

neue Show: TOPFt?glich (http://mrtopf.de/blog/category/topf-taglich/)
Loading...