[Zope-dev] ZPatterns, ObjectDomain, UML and all that.....

Steve Spicklemire steve@spvi.com
Mon, 4 Dec 2000 06:09:32 -0500 (EST)


I've been working out some issues with EMarket, and as a way to 'clear
the cruft'.. I decided to bite the bullet and do some more careful
object modeling. Other than scribbling on paper, and making up some
diagrams that look a little like those from Coad's book on Patterns
and Strategies, I've never used any object modeling tools before in my
life. Soooo... I downloaded the eval version of ObjectDomain, and I
can go for about 5 minutes on a Mac before it crashes, and usually 10
or 15 on Windows before it stops responding to mouse/keyboard
input. Save early, save often.. ;->. Sure it's frustrating.... but it
seems more workable that ArgoUML which I've had even less luck
with.... (What are other folks using? Rose?) anyway after much more
time that I would have thought possible I've come up with:

http://www.zope.org/Members/sspickle/EMarket/objectModel.gif

which is not finished, correct, or even totally consistent with the
current implementation, but it's a starting point. Based on this
picture.... I have some questions for other folks out there who are
doing object modeling and using ZPatterns, or who might just be
willing to comment on a first hack at a model for EMarket.

----------------------------------------------------------------------

1) One of my areas of confusion relates to the notion of an
'association'/'aggregation'. It seems that you can have a 'simple
association', which I guess just means that one object can talk to
another as equal 'peers'? This is denoted with a simple line, with no
bubbles at either end. There is also 'composite aggregation', with a
filled in bubble at one end (the container/master) and nothing at the
other (contained/slave?). Finally there is 'shared aggregation', where
there are multiple 'masters/containers' for a single 'slave/contained'
object. Each 'master' in this case has an 'empty' bubble. Object
domain has three labels for each connection. 1) a name for the
connection itself, 2) a name for the source/from end, and 3) a name
for the sink/to end.  In the current implementation of EMarket, since
the connections are actually implemented as Specialists, the only real
connections is that a master/container will have a (possibly) empty
list of ids that can be used to fetch the actual slave/contained
object from the corresponding Specialist(s). In the case of a 'two way
connection' would the connection have the name of one specialist in
one direction, and another in the other direction:

e.g., Shopper <--baskets ---- shoppers---> Basket)?  

Does this make sense? Are there other/better ways to think about 
and/or implement this idea with ZPatterns?

----------------------------------------------------------------------

2) I've stumbled on different ways to implement these things. 
I'm sure there are other (better?) ways as well. One way
e.g., is to store a 'barID' to make a connection, and a runtime, using

"bars.getItem(self.barID )"

to get it.. or.. store the Bar object itself in your DataSkin
and hope that everything will sort it self out when it is next
accessed. So far I've always kept an ID, then used getItem
at runtime, when I needed the 'real' thing....  I remember
some discussion on the list about keeping an Address object
in a related DataSkin, which sounds great.. but I have/had some
concerns. 

 My retrieval code often looks something like this:

  theBar = bars.getItem(self.theBarID)
  if theBar:
     foo = theBar.getFoo()
  else:
     # do something about the fact that there was no Bar.....

 If I explicitly store a Bar object as an Attribute of a DataSkin then
 what happens if the original Bar is removed from its Specialist's
 Rack? Does the Bar I store still refer to the original Rack as its
 DataManager? So.. does a Rack sometimes have 'clients' that are not
 really in the Rack at all? Or perhaps I misunderstood the discussion,
 and the Address wasn't really a DataSkin at all?  Also.. assuming
 that all works, do I have to do anything special, or carefully to be
 sure that the persistence machinery doesn't incur lots of expensive
 attribute fetching if I don't explicitly refer to those attributes,
 but have the DataSkin as a directly set attribute of another
 DataSkin?

Another approach is to make theBar a computer attribute, e.g.,

 WITH bars.getItem(self.theBarID) COMPUTE theBar=RESULT or NOT_FOUND

which is sort of a (nice?) compromise between the two approaches, but
it still requires that I keep an Id around.... 

Does anyone have comments/feedback on the merits of these different
approaches? I'd love to come up with a set of 'best practices' for
some of these issues. I'm trying to use ZPatterns, train other folks
on how to use them, and learn the nitty gritties all at the same
time... Life never used to be so interesting. ;->

----------------------------------------------------------------------

3) (Last question I promise!.. for now) Is there any real difference
between the plain lines, open bubbles, and closed bubbles other than
the number of (master) objects with relations to the (slave?). If both
objects refer back to eachother, should there be two bubbles? (That
doesn't seem to be an option with ObjectDomain.) Is there a good
source on the net that talks about this stuff? I've been reading some
of the specs at omg.org... and I'm guessing there's something out
there more friendly ... but I haven't found it yet...

----------------------------------------------------------------------

OK.. that's it. Any feedback would be appreciated. When I get it
all figured out I'll throw it all into the DumbZPatterns example
with your feedback.

thanks!
-steve