2009-05-19 58 views
4

因此,我正在编写一个应用程序,其中一个对象有一堆将它转发邮件的委托对象。这个想法是,我可以说Smalltalk中的邮件转发

someObject sendMessage:aMessage 

和aMessage将被发送到所有someObject的委托(对于任何值的aMessage)。我能够做到这一点的唯一方法是这样的:

sendMessage:aMessage 

| sel chunks kwords arglist msg | 
chunks := aMessage findTokens:' '. 
kwords := Array new:(chunks size). 
arglist := Array new:(chunks size). 
1 to: (chunks size) do: [:i | 
    kwords at:i put:((chunks at:i) findTokens:':') at:1. 
    arglist at:i put:((chunks at:i) findTokens:':') at:2]. 
sel := ''. 
kwords do:[:word | sel := sel,word,':']. 

msg := Message selector:sel arguments:arglist. 
delegates do:[:del | del perform:msg selector with:msg arguments]. 

它的工作原理,但必须有更好的方法。这个解决方案将参数限制为字符串,并且很简单。有没有人知道更清洁,更好的方式来转发消息?

顺便说一句,我使用的吱吱声,而是一个实现独立的解决方案会者优先;)

编辑:我要补充的是,代表是同一类的对象,这样我就可以”只是重写DoesNotUnderstand :.

回答

7

既然你想传递作为参数的对象,你就必须在将它们作为一个SE

someObject的sendMessage:aSelector withArguments:参数列表

然后你实现#sendMessage:withArguments:如:

的sendMessage使用如下消息模式的parate列表: aSelector withArguments:argumentList

委托人:[:del | del执行:aSelector withArguments :: argumentList]。

而且你可以转发使用真实对象作为ARGS任意复杂的消息:

|参数|

arguments:= Array with:Object new with:1234.5 with:('key' - >'value')。

someObject的sendMessage:#foo:条:巴兹:withArguments:参数

我觉得这是可以移植到大多数方言,以及...

2

尝试实现这一点(它只会转发邮件不是由对象了解,代表):

doesNotUnderstand: aMessage 
    delegates 
     do: [:delegate | aMessage sendTo: delegate] 

您可以构建信息明确对象,如:

msg := Message selector: #foo arguments: #(bar baz) 
"then use them like:" 
anObject perform: msg selector with: msg arguments 
+0

感谢您的建议,但对象与代表属于同一类型,所以我无法做到这一点。我将其添加到原始问题中。 – Alex 2009-05-19 19:09:47

+0

也许你可以为这个委托集合创建一个新类,然后使用doesNotUnderstand?如果不进行更明确的消息创建,它可能是最直接的方式。 – 2009-05-19 20:18:15

0

为什么不简单地使用多态,就是在你调用的每个对象的类中实现这个方法?然后你在你的对象方法中使用相同的名称来实现,它只是将一个调用委托给所有的子对象。喜欢的东西:

MyObjectClass>>someMethod 
subobjects do: [:each | each someMethod] 
1

好了,不知道aMessage是什么,因为你提到的所有代表的对象是同一类的,我会做一些事情,如:

MyobjectClass>>SendMessage: aMessage 

    self doSomethingUsefulOnThisInstanceIfApplicable: aMessage. 
    self dependents do: [:ea | ea SendMessage: aMessage ] . 

您可能还需要看,看是否使用下列任何消息可以为你工作:(这些都是从Cincom的VisualWorks中)

update: 
update:with: 
update:with:from: 
2

在佳乐,请参阅类ObjectTracer。您可以使用它截取所有发送给对象的消息。