encaminhamento de mensagens em Smalltalk

votos
4

Então, eu estou escrevendo um aplicativo onde um objeto tem um monte de objetos delegado que ele encaminha mensagens. A idéia é que eu posso dizer

someObject sendMessage:aMessage

e amessage será enviado a todos os delegados do someObject (para qualquer valor de amessage). A única maneira que eu fui capaz de fazer isso é algo como:

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].

Ele funciona, mas tem que haver uma maneira melhor. Esta solução limita os argumentos para serem cordas, e é simplesmente feio. Alguém sabe um aspirador, a melhor maneira de transmitir mensagens?

BTW, eu estou usando guincho, mas uma solução independente de implementação seria preferido;)

EDIT : Devo acrescentar que os delegados são da mesma classe como o objeto, então eu não pode simplesmente substituir doesNotUnderstand :.

Publicado 19/05/2009 em 19:31
fonte usuário
Em outras línguas...                            


5 respostas

votos
7

Desde que você quer passar objetos como argumentos, você terá que passá-los como uma lista separada de usar um padrão de mensagem como o seguinte:

someObject sendMessage: withArguments aSelector: argumentList

Então você implementar #sendMessage: withArguments: como:

withArguments aSelector:: sendMessage ArgumentList

delegados fazer: [: del | del executar: withArguments aSelector:: argumentList].

e você seria capaz de transmitir arbitrariamente mensagens complexas usando objetos reais como argumentos:

| argumentos |

argumentos: = Array com: Object nova com: 1234,5 com: ( 'chave' -> 'value').

someObject sendMessage: #foo: bar: baz: withArguments: argumentos

Eu acho que isso é portável para a maioria dos dialetos, bem como ...

Respondeu 20/05/2009 em 02:03
fonte usuário

votos
2

Em Squeak, consulte a classe ObjectTracer. Você pode usá-lo para interceptar todas as mensagens envia para um objeto.

Respondeu 20/05/2009 em 17:33
fonte usuário

votos
2

Tentar implementar isso (ela só vai encaminhar mensagens que não são compreendidas pelo objeto que tem os delegados):

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

Você poderia construir mensagem objetos explicitamente como:

msg := Message selector: #foo arguments: #(bar baz)
"then use them like:"
anObject perform: msg selector with: msg arguments
Respondeu 19/05/2009 em 19:42
fonte usuário

votos
1

Bem, sem saber o que amessage é, e desde que você mencionou todos os seus objetos delegados são da mesma classe, eu faria algo como:

MyobjectClass>>SendMessage: aMessage

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

Você também pode querer olhar para ver se usando qualquer um dos seguintes mensagens poderia trabalhar para você: (estes são de Cincom VisualWorks)

update: 
update:with:
update:with:from:
Respondeu 19/05/2009 em 21:18
fonte usuário

votos
0

Por que não simplesmente usar um polimorfismo, isto é, implementar este método na classe de cada objeto que você está chamando? Então você implementar em seu método de objeto com o mesmo nome, que apenas delegados uma chamada para todos os subobjetos. Algo como:

MyObjectClass>>someMethod
subobjects do: [:each | each someMethod]
Respondeu 19/05/2009 em 20:26
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more