Domanda

Quindi sto scrivendo un'applicazione in cui un oggetto ha un gruppo di oggetti delegati a cui inoltra i messaggi.L'idea è che posso dirlo

someObject sendMessage:aMessage

e aMessage verrà inviato a tutti i delegati di someObject (per qualsiasi valore di aMessage).L'unico modo in cui sono stato in grado di farlo è qualcosa del tipo:

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

Funziona, ma deve esserci un modo migliore.Questa soluzione limita gli argomenti ad essere stringhe ed è semplicemente brutta.Qualcuno conosce un modo più pulito e migliore per inoltrare i messaggi?

A proposito, sto usando squeak, ma sarebbe preferibile una soluzione indipendente dall'implementazione ;)

MODIFICARE:Dovrei aggiungere che i delegati sono della stessa classe dell'oggetto, quindi non posso semplicemente sovrascrivere DoesNotUnderstand:.

È stato utile?

Soluzione

Dal momento che si desidera passare oggetti come argomenti, si dovrà passare loro in un elenco separato di utilizzare un modello di messaggio simile al seguente:

  

someObject sendMessage: withArguments aSelector: ArgumentList

Poi devi implementare #sendMessage: withArguments: come:

  

sendMessage: withArguments aSelector: ArgumentList

     

delegati fanno: [: del |     del eseguire: withArguments aSelector::. ArgumentList]

e si sarebbe in grado di inoltrare i messaggi arbitrariamente complesse utilizzando gli oggetti reali come args:

  

| argomenti |

     

argomenti: = Array      con: nuovo oggetto      con: 1234.5      con:. ( 'chiave' -> 'valore')

     

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

Credo che questo sia portatile per la maggior parte dei dialetti così ...

Altri suggerimenti

Prova a implementarlo (inoltrerà solo i messaggi che non vengono compresi dall'oggetto that ha i delegati):

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

Potresti costruire oggetti Message esplicitamente come:

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

In Squeak, vedere l'ObjectTracer di classe. È possibile utilizzarlo per intercettare tutti i messaggi invia a un oggetto.

Bene, senza sapere che cosa è aMessage, e dal momento che lei ha citato tutti gli oggetti sono delegati della stessa classe, mi piacerebbe fare qualcosa di simile:

MyobjectClass>>SendMessage: aMessage

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

Si potrebbe anche voler guardare per vedere se si utilizza uno dei seguenti messaggi potrebbe funzionare per voi: (questi sono da Cincom VisualWorks)

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

Perché non è sufficiente utilizzare un polimorfismo, ovvero, implementare questo metodo nella classe di ogni oggetto che si sta chiamando? Poi si implementa nel metodo oggetto con lo stesso nome, che solo i delegati una chiamata a tutti gli oggetti secondari. Qualcosa di simile:

MyObjectClass>>someMethod
subobjects do: [:each | each someMethod]
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top