Look Again at the ZCA


Published on

This is the talk I gave on the Zope Component Architecture at Europython 2010. It gives a general outline of the ZCA concepts (Interfaces, Utilities and Adaptors) along with two examples where the ZCA would be useful.

Published in: Technology
1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Look Again at the ZCA

  1. 1. The ZCA Building elegant things
  2. 2. Overview • A real world problem. • An explanation of the core ZCA concepts. • A simple model of the problem to use during the talk. • Code to apply concepts in the context of the simple model.
  3. 3. The Problem Outline of the problem which led me to appreciate the ZCA
  4. 4. The newsletter problem • Types designed for display on the web which we couldn't edit. • But which were in a good class hierarchy. • But we need to reformat some of them for display in a newsletter—and format the rest in a generic manner. • And, as always, we’re on a deadline. • The ZCA can help us with this problem
  5. 5. A “standard” A Typical Day As Gregor Samsa awoke one morning from item just gets uneasy dreams he found himself transformed a title and in his bed into a monstrous vermin. More... description. Birthday News: “I feel no older” A news item After celebrating his 27th birthday, gets a picture a man claimed today to “feel no older” than the day before. More... beside it. Paris in the Autumn view the album And for a photo album, why not just some photos?
  6. 6. Modelling the problem • I’m going to use the problem I just described as a basis. • We’re going to work through a simplified version to go over the primary concepts in the ZCA. • First, let’s look at the concepts.
  7. 7. Core Concepts Fire up your diggers
  8. 8. Let’s talk about Zope • Zope = Zope Object Publishing Environment. • Zope’s model is that of an object graph. • Both content and functionality are stored in Zope’s object database (the ZODB). • Zope 2 was a bit all or nothing: inventing wheels, very interwoven.
  9. 9. I <3 Zope http://bit.ly/dtbNqj
  10. 10. Zope 3 • Zope 3 was the reformulation of Zope into components. • The ZCA was built to meld these components together into a web platform. • It’s not crazy.
  11. 11. The ZCA • A Service Locator—it helps the parts of your application find each other without tight coupling. • Components are registered with a central registry, which responds to queries. • Configuration decides what component provides a given function. • Though it would be possible to write a plugin architecture for your project, the ZCA is already there and well tested. We provide I need function X function X I can help
  12. 12. Interfaces • Defines a set of functionality a thing promises to provide. • A gentleman’s agreement, not a contract. • Can be implemented any object, unlike some other languages. • The core of the ZCA: • You can ask for an object which implements an interface; • Or an object to convert from one interface to another.
  13. 13. Interfaces ZODB LDAP User Code SQL DB isValidUser() addUser() removeUser() ISecurityProvider
  14. 14. Utilities • A utility is an object which implements a specific interface. • You register the object with the ZCA, telling the ZCA the object is a utility which implements the interface. • Then ask for it later from anywhere in your program.
  15. 15. Utilities ZODB LDAP User Code SQL DB isValidUser() addUser() removeUser() “implements” ISecurityProvider
  16. 16. Adapters • Adapters can convert from one or more interface to another. • In Zope they are often used to add functionality in addition to just altering and interface.
  17. 17. Adapters SQL DB Adapter User Code userIsOkay() userIsOkay() isValidUser() isValidUser() addUser() removeUser() ISecurityProvider
  18. 18. Multi-Adaptors • Multi-adaptors adapt more than one input interface to a single output interface. • Zope uses this for rendering pages by adapting as follows: HTTP Request View Adapter (rendered page) Content Item
  19. 19. Is this too far? • Zope 3 uses multi-adaptors to register event handlers: Like the snappily named Event type is IObjectModifiedEvent defined by Interface Callable which Adapter handles event Content Item
  20. 20. Work ed Exam ple
  21. 21. The simplified model Finder Selects items for sending Content to select from. IItemFinder Renderer for most items Rendering “Pipeline” Renderer for news items Renderer for photo albums INewsletterItemRenderer
  22. 22. Content Objects StandardItem SubStandardItem PhotoAlbum NewsItem
  23. 23. The content objects # Note they have no knowledge of the # ZCA. class StandardItem(object): class NewsItem(StandardItem): def __init__(self, title): def __init__(self, title, self.title = title description, date): self.title = title @property self.description = description def url(self): self.date = date """Generate a url""" [...] class SubStandardItem(StandardItem): class PhotoAlbum(StandardItem): """This item should be renderable by the adaptor for StandardItem""" def __init__(self, title, thumbnails): def __init__(self, title): self.title = title self.title = "SUB! %s" % title self.thumbnails = thumbnails
  24. 24. A utility to find them class IItemFinder(Interface): def __call__(): """Return a list of items which descend from StandardItem.""" class ItemFinder(object): implements(IItemFinder) def __call__(self): The ZCA bits """Hardcode for demo purposes""" return [ PhotoAlbum("Crocodiles", []), StandardItem("A Standard Item"), SubStandardItem("A second standard item"), NewsItem("Man Feels No Different on Birthday", """ Man reports feeling no different on 27th birthday from the day before.""", "10th July, 2010"), NewsItem("Less Newsworthy", """ The world is going to end tomorrow at 14.27.""", "13th June, 2010"), [... some more items ...] ]
  25. 25. Adaptors to render them class INewsletterItemRenderer(Interface): def render(): Our interface """Render an item""" class BaseRenderer(): """Base class to do what all the renderers need to do"""All renderers implements(INewsletterItemRenderer) def __init__(self, context): implement self.context = context class BaseContentToNewsletterBlockRenderer(BaseRenderer): the interface adapts(StandardItem) def render(self): and adapt a return "*** %s (Standard Item)n %s" % ( self.context.title, self.context.url) content item class NewsItemToNewsletterBlockRenderer(BaseRenderer): to it adapts(NewsItem) def render(self): return "*** %s (News)n %sn %snn %s" % ( self.context.title, self.context.date, self.context.url, [...format the body...] class PhotoAlbumToNewsletterBlockRenderer(BaseRenderer): [...]
  26. 26. Register them # These all use the Global registry. It's possible to # have separate registries if needed for your application. from zope.component import provideAdapter, provideUtility, getUtility # (1) A utility needs to be instantiated before registering. provideUtility(ItemFinder(), IItemFinder) # (2) Adaptors will be created as needed so don’t need # creating. provideAdapter(BaseContentToNewsletterBlockRenderer, (StandardItem,), INewsletterItemRenderer) provideAdapter(NewsItemToNewsletterBlockRenderer, (NewsItem,), INewsletterItemRenderer) provideAdapter(PhotoAlbumToNewsletterBlockRenderer, (PhotoAlbum,), INewsletterItemRenderer)
  27. 27. And use them Get the utility and call it to get item list: finder = getUtility(IItemFinder) items = finder() The ZCA will find the right renderer: body = "nn".join([ INewsletterBlockRenderer(x).render() for x in finder ]) Let’s go! print """ Dear subscriber, %s We hope you enjoyed this update, The Team. """ % body
  28. 28. Summary • ZCA allows for building robustly componentised applications. • Core is: Interfaces, Utilities and Adapters. • It’s well tested and small enough to easily learn. • It’s powerful enough for production use--and widely deployed. • Suggested further reading: http://www.muthukadan.net/docs/zca.html
  29. 29. Get in contact: mike@netsight.co.uk Thank you for watching! Or catch me in the hallways!