[Zope-dev] ZPatterns, ZClasses, Specialists: Assigning responsibilities

Itai Tavor itai@optusnet.com.au
Thu, 21 Dec 2000 17:13:40 +1100


Phillip J. Eby wrote:

>This should probably be more like:
>
>product.addMeToOrder():
>       item = OrderLineItems.newLineItemFor(self)
>	    item.setQuantity(...)
>       etc.
>       order.addLineItem(item)
>
>customizable_product.addMeToOrder():
>       item = OrderLineItems.newLineItemFor(self)
>       item.setGraphic(...)
>	    item.setQuantity(...)
>       etc.
>       order.addLineItem(item)
>
>This approach makes things more declarative.  The product classes can have
>properties or interfaces that the OrderLineItems specialist can use to
>decide what kind of line item would serve them best.  You can then change
>your line item assignment rules without necessarily requiring changes to
>the product classes.

Yeah, it does work much better your way. And, getting OrderLineItems 
to decide on its own which type of object to add - haven't thought 
about doing it this way before. Thanks - something new to meditate on.


>  >I imagine, then, that the UI for uploading the graphic would be
>>included in product.addMeToOrderForm, using a UI snippet from the
>>OrderLineItemsWithGraphic Specialist. Then I could pass REQUEST on to
>>order.addLineItem and to OrderLineItemsWithGraphic.add, which would
>>then upload the file?
>
>I think you're right about this being an OrderLineItem.  A couple of fine
>points, however...  First, I don't think there needs to be an
>"OrderLineItemsWithGraphic" specialist, since there is nothing else that
>would talk to it.  It's fine in this case to have the line item classes
>(either with graphic or without) handle their own UI snippets.  UI
>delegation is for when an object needs to display UI for some *other*
>object than itself, since you can always use class extenders and other
>techniques to reshape the apparent class of an object retrieved from a
>specialist.  The interface which other objects deal with is
>"OrderLineItem", and they simply expect a portion of the form to be
>rendered, and it's okay for the class to handle that.

I got a bit confused here... the UI snippet for uploading a graphic 
actually comes from the Graphics Specialist. If I want to let the 
user upload the graphic as part of the product's addToOrderForm, 
Product needs to get this snippet - but Products and Graphics don't 
know about each other in the object model, so Product would have to 
ask OrderLineItems (not OrderLineItemsWithGraphic  - I clearly don't 
need that) to get the snippet from Graphics for it, because it would 
violate Demeter if it talked directly to Graphics... Or I could 
eliminate the problem by uploading the graphic from a form displayed 
by the order line item after it has been added.


>Second, you need to define that interface so that the Order can give the
>line item constraints on how it does that UI, so it can share the screen
>and REQUEST with other objects/data that the Order needs.  One easy way to
>do this is to use a namespace parameter, that simply gives the line item a
>name prefix to use on its fields.  Alternatively, you can use the "record"
>approach, like this:
>
><INPUT TYPE="TEXT" NAME="lineitem1.desiredSize:record:int" VALUE="4">
><INPUT TYPE="FILE" NAME="lineitem1.imageFile:record:file">
>...
>
>The resulting REQUEST object from submitting the form will contain a single
>object, "lineitem1", with "desiredSize" and "imageFile" attributes, so
>you'll only have to pass a single parameter back to the line item.  I've
>never tried doing a record with a file in it before, so I don't really know
>how well that works.

I've been solving the REQUEST sharing problem using a prefix on form 
fields... but I like the "record" idea - it makes it much easier to 
pass the form data around... I'll try it with a file soon. I imagine 
it would work fine.


>  >Woof... so long. I'd appreciate any comments on this - especially on
>>the question on whether it's better to have a specialized type of
>>OrderLineItem, or to link the standard OrderLineItem to a Product
>>object in case of a standard product, or, in the case of a
>  >customizable product, to a new object which stores the graphic and
>>tracks the fabrication of the customized item.
>
>Here's the question...  how many behaviors are different in the order line
>item itself?  Are you also using fulfillment line items?  If the only
>difference to the order line item is that it references some additional
>data, then I'd say a single class would be fine.  Most of the behavior
>probably comes in on the fulfillment line item, yes?  Again, you can ask
>your FulfillmentLineItems specialist to create
>"newLineItemFor(orderLineItem)" and let it decide what kind of
>implementation to hand back.  In this case, it probably will be a different
>class, while for the order line items, it may or may not buy you anything.

I haven't thought of using fulfillment line items... not sure what 
they are for? An order is considered fulfilled once all items have 
been shipped, so order line items are responsible for tracking 
everything that happens until a ShipmentLineItem is created. The 
order line item for a customizable product tracks the product using 
state values like 'sent to factory', 'received from factory', etc. So 
it needs a new set of state values, as well as methods like 
'sendManufacturingOrderToFactory'.

What exactly does the fulfillment role you're referring to do? Does 
it do more than a shipment role?

Itai
-- 
Itai Tavor                    "Je sautille, donc je suis."
C3Works    itai@c3works.com              - Kermit the Frog

"If you haven't got your health, you haven't got anything"