cosa passa il messaggio in OO?

33

Ho studiato la programmazione OO, principalmente in C ++, C # e Java. Pensavo di aver capito bene con la mia comprensione dell'incapsulamento, dell'eredità e del polimorfismo (oltre a leggere un sacco di domande su questo sito).

Una cosa che sembra apparire qua e là è il concetto di "passaggio di messaggi". Apparentemente, questo è qualcosa che non viene usato durante la programmazione OO nelle lingue tradizionali odierne, ma è supportato da Smalltalk.

Le mie domande sono:

  • Che cosa passa il messaggio? (Qualcuno può dare un esempio pratico?)
  • C'è qualche supporto per questo "passaggio di messaggi" in C ++, C # o Java?
posta Tom 20.03.2012 - 09:06
fonte

3 risposte

58

What is message passing? (Can someone give a practical example?)

Il passaggio dei messaggi significa semplicemente che (ad un livello molto astratto) il meccanismo fondamentale dell'esecuzione del programma è rappresentato dagli oggetti che si scambiano messaggi. Il punto importante è che il nome e la struttura di questi messaggi non è necessariamente fissato in anticipo nel codice sorgente e può essere esso stesso un'informazione aggiuntiva. Questa è una parte importante di ciò che Alan Kay aveva originariamente immaginato come "programmazione orientata agli oggetti".

Is there any support for this "message passing" in C++, C# or Java?

Questi linguaggi implementano una versione limitata del messaggio che passa attraverso le chiamate ai metodi. Limitato perché il set di messaggi che possono essere inviati è limitato ai metodi dichiarati in una classe. Il vantaggio di questo approccio è che può essere implementato in modo molto efficiente e consente un'analisi del codice statica molto dettagliata (che si traduce in tutti i tipi di vantaggi utili, come il completamento del codice).

Viceversa, le lingue che impongono il passaggio di messaggi "reali" spesso hanno anche definizioni di metodo, un modo conveniente per implementare gestori di messaggi, ma consentono alle classi di implementare gestori di messaggi più flessibili che abilitano l'oggetto a ricevere "chiamate di metodo" con nomi arbitrari (non risolto in fase di compilazione).

Un esempio in Groovy che dimostra il potere di questo concetto:

def xml = new MarkupBuilder(writer)
xml.records() {
  car(name:'HSV Maloo', make:'Holden', year:2006) {
    country('Australia')
    record(type:'speed', 'Production Pickup Truck with speed of 271kph')
  }
}

produrrà questo XML:

<records>
  <car name='HSV Maloo' make='Holden' year='2006'>
    <country>Australia</country>
    <record type='speed'>Production Pickup Truck with speed of 271kph</record>
  </car>
</records>

Tieni presente che records , car , country e record sono sintatticamente chiamate di metodi, ma non ci sono metodi con quel nome definito in MarkupBuilder . Al contrario, ha un gestore di messaggi catchall che accetta tutti i messaggi e interpreta i nomi dei messaggi come il nome di un elemento XML, i parametri come attributi e chiusure come elementi secondari.

    
risposta data 20.03.2012 - 09:57
fonte
26

Il trasferimento dei messaggi è un modo diverso di gestire il bisogno nel codice OO di un oggetto per ottenere un altro oggetto (o potenzialmente se stesso) per fare qualcosa.

Nella maggior parte dei linguaggi moderni che discendono dall'approccio C ++ lo facciamo con le chiamate ai metodi. In questo caso l'oggetto chiamato (tramite la sua definizione di classe) mette una grande lista di ciò che il metodo chiama accetta e quindi il codificatore dell'oggetto chiamante semplicemente scrive la chiamata:

public void doSomething ( String input )
...
other_object.dosomething ( local )

Per linguaggi tipizzati staticamente, il compilatore può quindi controllare il tipo di cosa chiamata e confermare che il metodo è stato dichiarato. Per le lingue digitate dinamicamente, viene eseguita in fase di runtime.

In pratica, tuttavia, ciò che accade è che un fascio di variabili viene inviato a uno specifico blocco di codice.

Passaggio del messaggio

Nei linguaggi di passaggio dei messaggi (come l'Objective C) invece dei metodi ci sono i ricevitori, ma in generale l'approccio di definirli e chiamarli è praticamente lo stesso - la differenza è il modo in cui è gestita.

In un messaggio passato alla lingua il compilatore può controllare che il ricevitore che hai chiamato esista, ma nel peggiore dei casi verrà visualizzato un avviso per dire che non è sicuro che sia lì. Questo perché in fase di esecuzione ciò che accadrà è che un blocco di codice sull'oggetto ricevente verrà chiamato passando sia il fascio di variabili che la firma del destinatario che si desidera chiamare. Quel blocco di codice cerca quindi il ricevitore e lo chiama. Tuttavia, se il ricevitore non esiste, il codice restituirà semplicemente un valore predefinito.

Di conseguenza, una delle stranezze riscontrate durante lo spostamento da C ++ / Java - > L'obiettivo C sta nel comprendere che è possibile "chiamare un metodo" su un oggetto che non è stato dichiarato sul tipo in fase di compilazione e che non esisteva nemmeno sul tipo di runtime ... e che la chiamata non avrebbe comportato un'eccezione viene lanciata ma in realtà un risultato viene passato indietro.

I vantaggi di questo approccio sono che appiattisce la gerarchia delle sottoclassi ed evita la maggior parte delle esigenze di interfacce / tipi di ereditarietà / anatra multipli. Permette anche agli oggetti di definire il comportamento predefinito quando viene richiesto di fare qualcosa per il quale non hanno un ricevitore (comunemente "se non lo faccio, inoltra la richiesta a questo altro oggetto"). Può anche semplificare il collegamento ai callback (ad esempio per gli elementi dell'interfaccia utente e gli eventi programmati) in particolare su linguaggi tipizzati staticamente come Java (in modo che il pulsante possa chiamare il ricevitore "runTest" piuttosto che chiamare il metodo "actionPerformed" sulla classe interna "RunTestButtonListener" che ti chiama).

Tuttavia, sembrerebbe essere a costo della necessità di ulteriori verifiche da parte dello sviluppatore che la chiamata che pensano di fare sia sull'oggetto giusto con il tipo giusto e che passi i parametri giusti nell'ordine giusto, perché il il compilatore potrebbe non avvisarti e funzionerà perfettamente in fase di esecuzione (solo restituendo una risposta predefinita). C'è anche un colpo di prestazioni dalla ricerca extra e dal passaggio dei parametri.

In questi giorni, le lingue digitate dinamicamente possono offrire molti vantaggi del messaggio inviato OO con meno problemi.

    
risposta data 20.03.2012 - 10:47
fonte
9

Le architetture di passaggio dei messaggi sono semplicemente sistemi in cui ogni componente è indipendente dagli altri, con un meccanismo comune per il trasferimento dei dati tra di loro. Puoi considerare le chiamate ai metodi come una forma di trasmissione di messaggi, ma non è pratico farlo - confonde il problema. Questo perché se si dispone di una classe con metodi ben definiti e di un codice che chiama tali metodi, l'intera cosa deve essere compilata insieme, quindi accoppiando il codice e l'oggetto. puoi vedere come è chiuso (come viene passato un messaggio e il compilatore sta applicando la correttezza, ma perde gran parte della flessibilità di un sistema disaccoppiato).

Le architetture di passaggio dei messaggi spesso consentono di aggiungere oggetti in fase di runtime e, molto spesso, di consentire il reindirizzamento dei messaggi a uno o più oggetti. Quindi posso avere un codice che trasmetta un messaggio 'data x is updated' a tutti gli oggetti che sono stati caricati nel sistema, e ognuno di essi può prendere qualsiasi azione che gli piace con quelle informazioni.

Un bizzarro esempio è il web. HTTP è un sistema che trasmette messaggi: si passa un verbo di comando e un "pacchetto di dati" a un processo del server. (ad esempio, GET http: \ myserver \ url) Né il tuo browser, né il server web si preoccupano dei dati che invii o dove li invii. Il server lo passerà al codice che impacchetterà un altro "pacchetto" di dati e lo rispedirà a te. Nessuno dei componenti di questo sistema sa nulla del lavoro degli altri o di quello che fanno, conoscono solo il protocollo utilizzato per la comunicazione dei messaggi.

    
risposta data 20.03.2012 - 17:01
fonte

Leggi altre domande sui tag