zope.component
zope.component is a reusable python package that usually comes with zope.interface and zope.event. We can split this package into two categories:
- Components: adapters, utilities, named adapters, multi-adapters and others
- Registries: global component registry, local component registry.
What we need to remember from all this is that there are registries that store adapters. The idea is to use these registries through out our application. Think of it as a global dictionary with values: adapters and keys: interfaces – because it’s exactly what it is. Without further ado we’ll jump directly to a simple example, but instead of adapters will use an utility (an adapter that adapts nothing).
A small utility
Let’s see what we did here:
- We declared an interface and an utility class Hello.
- We got the global registry and registered our utility for the ISpeach interface.
- In the end we used our utility first by querying the register and then just used it as a Hello object.
The benefits
The nice thing about registering a utility like this is that you can change its location in the project, you can refactor it and give it a different name, you can override it with another utility at will – and most importantly is that the last 2 lines never change! Here is why:
- All we really care about is the interface with which we are making the query – the implementation can change in the future.
- The code is decoupled (no direct imports to the implementation) – just the interface is known to us.
A direct result to this is: more control for the developer which can replace the implementation at will without worrying that he/she needs to refactor a lot of code. Looks like a lot of code just to register one simple utility isn’t it? I couldn’t agree more, but remember that we are talking here about big applications with tons of utilities and adapters and events and event handlers. In the end everything is a structured chaos. It’s structured because as long as we have a registry that has all the components we have an overview of our application and all its components.
But my application is already far in it’s 3rd year of development. I don’t have everything in one big component registry!
The good news is that you don’t need to have everything as components – I strongly advice against it actually. You can use this just for the parts you feel that your application will benefit the most. You can gradually use it where it makes sense.
Now let’s return to our apples and oranges example, but make it use adapters.
Oranges and Apples – again
It’s really not that different from our previous example with apples and oranges except the whole interfaces and registration stuff. The benefit however is that this is a lot more usable in the long run for the reasons I explained above. And the difference from the utility example is that it actually adapts something – IApple in our case. The key thing to remember is that all the registry queries are done using interfaces.
In the next part I will try to draw the big picture, what else can components do besides adapters and utilities and what I personally don’t like about their implementation – discussing possible alternatives.
