Using multi-adapters a la Zope
As a brief discussion (and I should mention that this has nothing to do with a web application), you have an object and you want to look at it. Imagine you have gone the whole way with this concept and you have arrived at Zope. Zope contains mechanisms for definition, storage and manipulation of objects, all using Python.
So you have an interface:
Ok, it's simple. Now you write a class that implements this, still simple.
Pretty good. You can store that in an object database like ZODB if you like, but we are going to think how to view it.
A view (in Zope terminology) is something that adapts (multi-adapts) a "context" and a "request". We don't really understand what a "context" is, so we are going to call it an "object". A request can be something like "edit" or "view".
So of course we need an interface for views to adhere to, and an interface for a request to adhere to. This is where interfaces stop being documentation niceties, and start being implementation nasties.
So imagine we implement a simple view (now remember this is nothing to do with a web application). The view will display Fruit objects.
And also a request implementation that does nothing
And we are ready to go:
gives you
So you have an interface:
from zope.interface import Interface, Attribute
class IFruit(Interface):
name = Attribute("""The name of the fruit""")
Ok, it's simple. Now you write a class that implements this, still simple.
class Fruit(object):
implements(IFruit)
def __init__(self, name):
self.name = name
Pretty good. You can store that in an object database like ZODB if you like, but we are going to think how to view it.
A view (in Zope terminology) is something that adapts (multi-adapts) a "context" and a "request". We don't really understand what a "context" is, so we are going to call it an "object". A request can be something like "edit" or "view".
So of course we need an interface for views to adhere to, and an interface for a request to adhere to. This is where interfaces stop being documentation niceties, and start being implementation nasties.
class IView(Interface):
def render():
"""Display what needs displaying"""
class IViewRequest(Interface):
user = Attribute("""The user that made the request""")
So imagine we implement a simple view (now remember this is nothing to do with a web application). The view will display Fruit objects.
from zope.component import adapts, provideAdapter, getMultiAdapter
class FruitView(object):
implements(IView)
adapts(IFruit, IViewRequest)
def __init__(self, fruit):
self._fruit = fruit
def render(self):
print self._fruit.name
# not forgetting to register the adapter with zope.component
provideAdapter(FruitView)
And also a request implementation that does nothing
class ViewRequest(object):
implements(IViewRequest)
user = None
And we are ready to go:
view = getMultiAdapter((Fruit('banana'), ViewRequest()), IView)
view.render()
gives you
banana