惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Fox-IT International blog
Recent Announcements
Recent Announcements
D
Docker
IT之家
IT之家
B
Blog
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 【当耐特】
Google DeepMind News
Google DeepMind News
F
Fortinet All Blogs
量子位
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
博客园 - 司徒正美
李成银的技术随笔
美团技术团队
Blog — PlanetScale
Blog — PlanetScale
雷峰网
雷峰网
The GitHub Blog
The GitHub Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
T
The Blog of Author Tim Ferriss
酷 壳 – CoolShell
酷 壳 – CoolShell
MongoDB | Blog
MongoDB | Blog
P
Proofpoint News Feed
L
LangChain Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
有赞技术团队
有赞技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
T
Tailwind CSS Blog
H
Help Net Security
Engineering at Meta
Engineering at Meta
小众软件
小众软件
B
Blog RSS Feed
Stack Overflow Blog
Stack Overflow Blog
月光博客
月光博客
M
Microsoft Research Blog - Microsoft Research
宝玉的分享
宝玉的分享
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
GbyAI
GbyAI
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Last Week in AI
Last Week in AI
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog

Secret Weblog

Becoming More Xee: A Modern XPath and XSLT Engine in Rust Looking for new challenges! Repeat Yourself, A Bit The Curious Case of Quentell The Humble For Loop in Rust The Humble For Loop in JavaScript Don't Look Down on Print Debugging Question Best Practices I Was a 1980s Teenage Programmer Part 5: Achieving Assembly I Was a 1980s Teenage Programmer Part 4: The Call of Assembly The Tooling Shift I Was a 1980s Teenage Programmer Part 3: MSX-2 JavaScript: when you need two ways to do it! Empowering Programming Languages Bloat and Retrofuturism Refreshing my Blog Again Random Rust Impressions Apilar: An Alife System I Was a 1980s Teenage Programmer Part 2: Olivetti M24 I Was a 1980s Teenage Programmer: the Alphatronic SolidJS fits my brain Is premature optimization the root of all evil? Framework Patterns: JavaScript edition Roll Your Own Frameworks Looking for new challenges Framework Patterns Secret Weblog Highlights Refactoring to Multiple Exit Points mstform: a form library for mobx-state-tree Seven Years: A Very Personal History of the Web Looking for new challenges Morepath 0.16 released! Is Morepath Fast Yet? Introducing Bob Strongpinion Punctuated Equilibrium in Software Morepath 0.15 released! Impressions of React Europe 2016 Morepath 0.14 released! Morepath 0.13 now with Dectate Dectate: advanced configuration for Python code JavaScript Dependencies Revisited: An Example Project The Incredible Drifting Cyber A Brief History of Reselect The Emerging GraphQL Python stack Thoughts about React Europe Build a better batching UI with Morepath and Jinja2 GraphQL and REST Server Templating in Morepath 0.10 10 reasons to check out the Morepath web framework in 2015 A Review of the Web and how Morepath fits in Morepath 0.9 released! Better REST with Morepath 0.8 Morepath 0.7: new inter-app linking They say something I don't like so they must be lying! Life at the Boundaries: Conversion and Validation BowerStatic 0.4 released! Morepath 0.6 released! Morepath 0.5(.1) and friends released! New HTTP 1.1 RFCs versus WSGI Against On Naming In Open Source My visit to EuroPython 2014 Morepath 0.4.1 released (with Python 3 fixes) Morepath 0.4 and breaking changes Announcing BowerStatic Morepath 0.3 released! Morepath 0.2 Morepath Python 3 support The Call of Python 2.8 Morepath 0.1 released! WebOb and Werkzeug compared Morepath: from Werkzeug to WebOb Racing the Morepath: SQLAlchemy Integration The Centre Cannot Hold Breaking Morepath Changes Morepath Update How to do REST with Morepath Morepath Security the Gravity of Python 2 #python2.8 discussion channel on freenode Alex Gaynor on Python 3 Morepath Documentation Starting to Take Shape Back to the Center Morepath App Reuse Implementing Grok Grok: the Idea Why Linux Works for Me On the Morepath Reg, Now With More Generic! The New Zope as a Web Framework Jim Fulton, Zope Architect Renewing Zope Object Publishing The Weirdness of Zope The Rise of Zope My Exit from Zope Reg: Component Architecture Reimagined JSConf EU 2013 impressions Obviel 1.0!
The Success of the Zope Component Architecture
Martijn Faassen · 2009-11-06 · via Secret Weblog

Prompted by recent brief negative pronunciations by Malthe on the Zope Component Architecture (ZCA), I thought I'd talk a bit about what I think about it. I'm not going to go into hermeneutics here of what Malthe might mean -- others attempts at exegesis exist in the comments to that blog entry already. Instead, I'll just talk about what I think makes the ZCA useful, and why it is successful. Finally I'll go into some reasons why people are frustrated by the ZCA.

What is the ZCA used for?

What is the ZCA used for? It's used to glue things to each other: glue event handlers to events, glue views to models, glue plugins into applications and libraries, and more abstractly, glue adapters to adaptees. In ZCA terms, providing such glue is termed providing configuration.

Why was the ZCA created? The Zope community had been building pluggable web applications for a long time and we noticed our components became overly complex and were hard to glue together and override. The ZCA is one answer to this problem.

The ZCA is implemented by zope.component. It's a library for gluing. It's built on top of zope.interface, a library that helps one define the bits that are being glued.

What advantage does such gluing bring?

  • many, perhaps all, larger applications contain glue. The ZCA makes the glue explicit and uniform.
  • ZCA glue can be overridden explicitly.
  • you can extend existing systems by gluing in new things.

One place where the ZCA is helpful is when you want to write a library that offers a few plugin points to configure it for a particular environment. For instance when I wrote hurry.resource, a library for handling javascript and other resources, I included a few plugin points in it that allow it to be plugged into a particular web framework. Then to allow it to be used with Zope Toolkit-based frameworks such as Grok, I wrote hurry.zoperesource to provide the knowledge about that.

This way, hurry.resource doesn't need to know anything in particular about URL generation or requests; its plugins can take care of this. This allowed me to write and test hurry.resource without worrying too much about the larger Zope Toolkit framework, knowing I could plug it in later, and now the library becomes more useful for a broader group of people.

The ZCA doesn't just allow one to glue one thing to another, but also to override the glue in specific cases. A common example of overriding glue occurs with views. Zope Toolkit applications follow a view/model approach, where the view is looked up on the model dependent on its class (or interface). It happens frequently enough in an application that I want many models to share a particular view, but override one model with a more specialized view. This is much like the way inheritance works in plain Python: I implement a method on a base class shared completely by some subclasses, but for one subclass I'd like to override it.

What I described just now is overriding for particular subclasses. The ZCA also allows other ways of overriding based on the zope.configuration library, overriding one glue registration with another one. I myself find myself using this kind of override less frequently, but it's still very useful in the 1 percent of cases where other options would be very ugly.

The question is sometimes asked why not just modify code dynamically for overrides? Why not monkey patch it? (or "open the class", or whatever other terminology one would like to use).

Brandon Rhodes at PyCon 2008 gave a great presentation explaining why the ZCA approach can be superior to monkey-patching and some other approaches. The point he makes is that the ZCA is the most composable and maintainable approach of the alternatives (subclassing, mixins, monkey-patching, adaptation). I recommend everyone interested in this topic to read his slides.

Of course as with everything in programming, everything depends on the trade-offs. In many circumstances the ZCA is overkill. The ZCA can be misused. But I also maintain that in many circumstances the ZCA is very useful.

Component approaches have become quite popular with web frameworks. Many popular ones adopt elements of it, but often in a somewhat limited way. For instance, one very popular interface is the WSGI interface, and one popular form of adaptation of this WSGI interface is to use WSGI middleware and framework components. With WSGI we see that just one well-defined, consensus interface has become an amazing source of creativity and pluggability within web development. With the ZCA we are able to define more than one interface in our applications, and potentially create ecosystems of creativity around those. Not that this is easy, but at least we have a mechanism and method to do so.

The ZCA is successful

Why do I say the Zope Component Architecture (ZCA) is successful? It's successful as it's being used, by many people, for many years now. Of course you can say it's only used by that weird Zope community, and a bit by weird Twisted people as well perhaps. That's fine, but realize that the wider Zope community is big and is made of many parts: Plone, Silva, Zope 2, Zope Toolkit, Grok. I'll also count BFG as part of the wider Zope community.

The ZCA is successful for me. Without it, I'd have to invent something very much like it. It comes back in much code that I've written. I'm able to do all kinds of small, cool things in my applications and libraries on a daily basis, and I'm creating more reusable code as a result.

Frustration with the ZCA

The ZCA isn't perfect. Humans aren't perfect, either. It's not easy to create good reusable interfaces, or to build pluggable frameworks and applications. It's easy to overdo the pluggability. It's easy to create the wrong pluggability points. It can get overly complex and overwhelming.

Writing XML configuration files to glue things together can be cumbersome and lead to repeating yourself, though his last issue has been overcome for some time now by the Grok project and its reusable solution (grokcore.component) is available to everybody.

It's easy to let the pain of the mistakes in the use of the ZCA, and the pain of complex applications in which it is used in general, overshadow the many successes of the ZCA: in a large part thanks to to the ZCA's ability to glue things together people are able to use Zope Toolkit libraries within a Zope 2 or Plone context. Grok was able to remix the Zope Toolkit in part because we could easily modify and extend the framework. I think the web frameworks that use the ZCA offer pluggability and flexibility unrivaled by the competition.

We generally don't say that the problems and complexities in our large libraries and applications are due to the Python programming language. While Python isn't perfect, we tend to think overall it helps. I also tend to think that the ZCA helps.

Are there alternatives to the ZCA? Certainly: any library or application specific pluggability system is an alternative. Sometimes a specific approach is better than a generic one. It can be easier to understand it's smaller.

Usually I'd say it's the other way around. Each custom pluggability system is another one to learn, and has its own limitations. I've found multiple times that I can make a far more powerful pluggability system for a library in a shorter time if I build it on top of the ZCA.

There are also more general approaches where there's at least some overlap with the ZCA: setuptools entry points, WSGI middleware, and PEAK-Rules. To use any of them for pluggability and overriding one needs to have a notion of an interface one can implement and plug into, a notion that the ZCA makes explicit.

Conclusions

The ZCA is useful. The ZCA is powerful. The ZCA is successful. The ZCA is imperfect. When I've run into its imperfections I've helped build solutions on top of it, such as Grok's in-python gluing approach. Sometimes I've considered its use overkill and gone for some other approach. I think it's useful to step back and consider alternative approaches. But let's consider them in the light of the success of the ZCA as much as in the light of its flaws.