[PEAK] PyProtocols --

Gabriel Jägenstedt gabriel.j at telia.com
Mon Feb 16 17:32:13 EST 2004


On Mon, 16 Feb 2004 11:19:45 -0500
"Phillip J. Eby" <pje at telecommunity.com> wrote:

> 
> So far, it's sounding to me like what you want is sort of like the San
> 
> Francisco "Extensible Item" pattern, which is like a cross between the
> 
> "Composite" and "Chain of Responsibility" patterns.
> 
> To be more specific, it sounds like you need for objects to ask their 
> contents to respond to messages from the outside world.  So, you could
> have food contain a Poison object, for example, and then it would
> respond to the IEdible behavior.
> 
> Notice, by the way, that this isn't inheritance; you don't inherit
> from Poisonous to make somethign poisonous, you instead make a Poison
> instance a part of the object.  Same thing for the lock on the book or
> the door.
> 
> So, the basic idea is that to perform an operation like "eat", you
> simply go through the object's contents in a post-order traversal, and
> adapt things to IEdible.  Sort of like this:
> 
>/snip/

Not that I understand all the words or all the details but I think I'm
getting the general idea. I like most of what I see but have some slight
considerations about specific implementation details. These details
however are mostly trivial and nothing that I should put onto you to
solve.

I can't seem to find any mention of any ICompositie, would you mind
pointing me in the right direction? What is it?

I notice that you use Interface not just for documentation but actually
providing a usefull function. I like it a lot and especially the fact
that we pass in commandObj, or in the case of PUB I belive an instance
of Command. Command supplies all and more information one could want
about a command.

oh and why on earth is there a parameter klass? I've seen it before
around here, but I can't figure it out. Is it a strange word for self
and if so why?

> So, each object gets an iterator that yields the next object in the 
> post-order traversal that implements the desired interface, or if
> there are no candidates remaining, it returns the default
> implementation provided by the interface itself as a class method. 
> Each invoked method has the opportunity to call
> 'chain.next().whatever(chain,...)' to get the result of a sort of
> "super" call.
> 
> So, if you need to implement weight, you could call 
> 'invoke(ob,ICarriable,"getWeight",commandObj)', and each object's 
> implementation would look like:

Correct me if I'm missing something but how can we possibly test the
truth of invoke when it has no return statement? I was under the
impression this will always become false..

> For openability, you'd have a door implement IOpenable, but if it
> contains a lock, the lock would get the chance to refuse to be opened,
> unless it was unlocked, in which case it would call 
> 'chain.next().open(chain,commandObj)', thus invoking the door's open()
> method.

Now this is where I'm unsure or rather I'm very unsure about several big
design issues. It looks like We'll be needing a lot of adapters. Or
maybe not, when it comes to many adapters are most likely game specific.
If we just provide a decent amount of good and sturdy adapters and
interfaces it should be fairly simple to create adapters for game
authors. I'll just have to figure out some mechanisms to make creation
simple. A nice and big objectlibrary should be of much help.

The biggest problem will be to determine what should be Interfaces and
what should be adapters.

> This is of course all very high-level.  I don't know what your
> 'commandObj' looks like, or whether you even have one, or whether you
> pass other arguments to these verb-ish methods.  You might also
> refactor this in various other ways.  For example, you might put the
> player and the object's he's carrying into the chain of
> responsibility, or maybe even include the room as part of the chain,
> and having verb-ish methods check the target of the command object to
> see if it is them that is being eaten or opened or whatever.  This
> would let you do things like having something be poisonous if it's
> eaten in a particular room, for example.  At that point, IEdible would
> probably be more meaningfully called IEatingListener, since it doesn't
> mean the object is edible, only that it wants to know about
> eating-related events.
> Anyway, as a whole, this approach appears to satisfy your main 
> criteria.  You do not need lots of multiple inheritance, for example. 
> You can create lots of fine-grained "aspect" objects (like Poison) and
> 
> relatively simple components (like Lock), and then use them as parts
> to assemble more complex objects.  These aspects and subcomponents can
> then override the behavior of the parent components, if/when they
> desire to do so.
> 
> The only drawback to the approach as I've presented it is that you can
> only delegate to one method of the 'chain.next()' object, because
> iterators aren't repeatable.  However, that can be solved with:
> 
> nextOb = chain.next()
> chain = list(chain)
> 
> nextOb.method1(iter(chain),commandObj)
> nextOb.method2(iter(chain),commandObj)
> 
> # etc.


I'm gratefull for all the help you've given me. I'm very much looking
forward to using protocols and playing around with the many
possibilities it gives me and PUB. I'll try to dive deeper into these
examples and create small tidbits of code myself to test how it all
works in a big picture.

 _______________________________________________
> PEAK mailing list
> PEAK at eby-sarna.com
> http://www.eby-sarna.com/mailman/listinfo/peak


-- 
//gabriel - a true believer



More information about the PEAK mailing list