所以我正在编写一个应用程序,其中一个对象有一堆转发消息的委托对象。这个想法是我可以说
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].
它有效,但必须有更好的方法。这个解决方案将参数限制为字符串,并且只是简单的丑陋。有谁知道更清晰,更好的转发消息的方式?
BTW,我正在使用吱吱声,但是首选的是独立于实现的解决方案;)
编辑:我应该补充一下,委托与对象属于同一个类,所以我不能只重写DoesNotUnderstand:。
答案 0 :(得分:7)
由于您希望将对象作为参数传递,因此您必须将它们作为单独的列表使用消息模式传递,如下所示:
someObject sendMessage:aSelector withArguments:argumentList
然后你实现#sendMessage:withArguments:as:
sendMessage:aSelector withArguments:argumentList
代表做:[:del | del perform:aSelector withArguments :: argumentList]。
你可以使用真实对象作为args转发任意复杂的消息:
|参数|
参数:=数组 with:对象新 与:1234.5 with :('key' - >'value')。
someObject sendMessage:#foo:bar:baz:withArguments:arguments
我认为这对大多数方言都是可移植的......
答案 1 :(得分:2)
尝试实现此功能(它只会转发拥有代理人的对象无法理解的消息):
doesNotUnderstand: aMessage
delegates
do: [:delegate | aMessage sendTo: delegate]
您可以显式构造Message对象,如:
msg := Message selector: #foo arguments: #(bar baz)
"then use them like:"
anObject perform: msg selector with: msg arguments
答案 2 :(得分:2)
在Squeak中,请参阅ObjectTracer类。您可以使用它来拦截发送给Object的所有消息。
答案 3 :(得分:1)
好吧,不知道aMessage是什么,并且既然你提到你所有的委托对象属于同一个类,我会做类似的事情:
MyobjectClass>>SendMessage: aMessage
self doSomethingUsefulOnThisInstanceIfApplicable: aMessage.
self dependents do: [:ea | ea SendMessage: aMessage ] .
您可能还想查看以下任何消息是否适用于您:(这些来自Cincom VisualWORKS)
update:
update:with:
update:with:from:
答案 4 :(得分:0)
为什么不简单地使用多态,即在你调用的每个对象的类中实现这个方法?然后使用相同的名称在对象方法中实现,该方法只委托对所有子对象的调用。类似的东西:
MyObjectClass>>someMethod
subobjects do: [:each | each someMethod]