[Zope3-dev] Interfaces as factories

Nicholas Seckar nseckar at yahoo.com
Thu Jul 1 23:56:27 EDT 2004


Hello all,

Here's a proposal-proposal I've come up with; I'd be
interested in hearing your thoughts. (The "Risks"
section has been left as an exercise. ;-) In a single
sentence, it reads as "Why content_class=X isn't such
a great thing, and here is a possible alternative."

Commonly in component code we specify a content
factory to use; sometimes in ZCML, sometimes in
Python. By defining the content factory to use, we
	i) Require the given factory to be available at the
given module path, thus forcing one component to be
dependant on another package's structure. (ftnote 1)
	ii) Define only one factory to produce content
objects, thus decreasing flexibility, or using a
selector factory, thus decreasing extensibility.
	iii) In some cases, we define the factory to use in
Python code, whereas this behavior should reside in
the realm of configuration.

To avoid these issues, code should not instantiate
objects from a class or factory, but from an
interface. Interfaces would then become not only
structure specifiers, but also factories.

To perform this type of action, an interface must know
all factories which implement it. Thus, content
factory registration becomes neccessary. (Luckily, we
already have 'implements(IMyInterface)'.) In addition,
an interface must be able to select the correct
factory for a given instantiation request. This
implies that interfaces should be configurable in
order to allow developers to write selection-logic as
required.

Using interfaces to instantiate objects also gives us
the abilty to easily extend. By adding a implementing
factory to an interface, a developer can extend the
functionality of all the components that use that
interface.

While using interfaces instead of factories adds some
flexibility, most of the dependance is merely shifted
to the module path of the interface, which is almost
as volatile as the path to a factory:
'zope.x.y.interfaces.ISomething' depends on the y
package always being in the same location.

The proposed solution to this is to create a
centralized interface repository to avoid 'Module not
found' errors. Interface lookup would be performed via
an object with an overloaded __getattr__, which would
be placed in the zope package with a path such as
'zope.interfaces'. Packages could then register their
interfaces through ZCML, and specify a fitting
pseudo-module path, such as

'zope.interfaces.components.textual.IRestructuredTextSource'
Instead of these paths representing package structure,
which is not always static, these paths would
represent functionality, which, for most interfaces,
should be static.

With an abstract repository, interfaces could also be
registered at more than one path; this would be useful
when an interface's path does need to change.

One of the best net gains this would bring is
extremely loose coupling. One of Java's big issues is
how closely coupled one class is to another. This
travesty is perpetrated mostly by strong typing, but
also by requiring exception 'throws' clauses. <rant
class="offTopic" tal:content="context/antiJavaRant" />

By using interfaces to both instantiate and contrain
objects, individual packages will be 'like an island'
in concrete dependancies, but easily extensible and
configurable: extensible by new interface
implementors, and configurable by the interface
selection logic.

The nature of Python gives Zope 3 decently loose
coupling; by adding this machina, we will be taking
the a step towards total abstraction. (We'll know that
we've gotten there when not even the best of us know
what we're doing. <wink/>)

A quick (hypothetical) example:
	Consider an IFile interface, specifying a mime-type
and the file contents.
	The selection logic would be implemented as a map
from mime-types to IFile factories. (These might be
other interfaces, such as IImage.)
	The default IFile factory would choose one of
BinaryFile or TextFile.

	When adding a 'image/png', the IImage file factory
would be used. The IImage interface might in turn use
a PNGImage factory.



Footnote 1:
	Relying on the underlying structure of abstract
objects is a bad thing, which is the reason Java uses
private variables. (That said, I fail to see how getX
and setX are an improvement.) Relying on the structure
of a package is even more dangerous, because packages
are organizational units; organization is often more
arbitrary that the structure of an object, and thus it
changes more often.



		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 


More information about the Zope3-dev mailing list