UML and Python
hancock at anansispaceworks.com
Wed Jan 22 23:00:48 CET 2003
Terry Hancock wrote:
> Does UML work for Python?
> Pluggable Brains
Thanks for all the useful (even if conflicting) opinions!
I have found the class-diagrams useful for defining my interfaces and
object model. After some installation frustrations, I opted to stick with
dia, at least for now. I'm using a newer version (0.88.1) than before
which doesn't segfault on me (at least not so far). Looks like this will
be good enough for the paper I'm writing.
I opted to represent interfaces (using Zope's interface/component model) as
"abstract classes with stereotype 'interface'", "implemented by" a concrete
class. I also use the naming convention of:
LumAPI -- an interface specification
Lum -- the simplest or most obvious implementation of LumAPI that
NonLum -- a null-implementation that pretends to work, but does nothing
useful (sometimes useful as a placeholder).
Elle -- Can use other names to represent different / less-obvious
implementations of the same API.
ReiAPI -- can be a pluggable brain API, in which case the stereotype is
ReiPB -- a "pluggable brain" implementation class. I borrowed the
"document" symbol from the "flowchart" package to document
what record/query the PB extends.
Rei -- an DB querying object that provides methods to access the
database table. The query methods return a "list of ReiPB".
This is a bit briefer than "Lum"=interface,
"LumImplementation"=implementation, which is what the Zope product DevGuide
has. I also find it more descriptive, since "the thing itself" has the
more basic name, while the more removed symbol of the thing has a modified
name letting you know what it is.
However, rather than focusing on objects or even classes, I'm focusing on
the interfaces. If an interface A "contains" another interface B as an
attribute b, that means that "an object implementing interface A must
contain A.b which implements interface B". That's nice, because in
principle, the interface doesn't care what sort of objects A & B are, so
long as they exhibit the correct behavior ("polymorphism"?). To make this
work still better, I'm going to have to replace my "meta-type" checks in
Zope with "implements" checks.
Since I don't list methods or attributes that are already specified by the
interface, I wind up with implementation classes being nothing more than a
name in a box, for the most part, with one or more "implements" arrows,
with only a very few exceptions.
Acquisition has to do with the deployment of class instances, and I haven't
tackled that yet, so I'm not positive how I'll do it.
Another uniquely Python trick that I will need to use "stereotypes" for is
the "monkeypatch" arrow where a live object is modified by adding an
attribute at runtime. An admittedly dangerous technique, but sometimes
necessary, and I don't think you can do it in other languages. ;-)
One thing I like about this process, is that an overblown API shows up like
a sore thumb, which encourages me to find ways to simplify. Which is
really good, because I have a few in my current package that I'm working on
clearing away now. Also good for improving the consistency of labels (i.e.
that the "summary()" method should do something similar when applied to two
different content objects, even if the whole interface is not copied.).
So I'm having to bend it a little, but UML is still proving fairly useful.
Thanks for the comments!
More information about the Python-list