2011-10-19 9 views
15

Qualcuno potrebbe spiegare la differenza tra l'inoltro e la delega? Sembrano simili, ma non sono stato in grado di trovare una buona definizione di inoltro, quindi non sono sicuro di averlo capito veramente.In OOP, che cos'è l'inoltro e in che modo è diverso dalla delega?

+0

Non so perché questo è stato votato in basso ... Sembra una domanda utile, anche se potrebbe usare un po 'più di elaborazione. Sfortunatamente, potremmo essere in un Catch-22 qui. Cercherò di fornire una risposta e l'interrogante può dirmi se ho capito bene. –

risposta

2

Sono idee simili in cui un oggetto si affida a un altro per chiedere aiuto. Ecco come penso alle due idee date il mio forte pregiudizio Objective-C:

delegazione: Una decisione deve essere presa, ma io non voglio farlo. Lascerò che il mio delegato lo gestisca.

In Cocoa, ad esempio, NSTableView utilizza un delegato per personalizzare il comportamento della tabella. La delega offre un modo per personalizzare un oggetto lasciando che un altro oggetto, il delegato, fornisca la personalizzazione. Continuando con l'esempio, il delegato di una vista tabella implementa un'interfaccia NSTableViewDelegate che la tabella utilizza per comunicare con il suo delegato.

inoltro: Qualcuno mi ha appena inviato un messaggio che non capisco, ma conosco un altro oggetto che potrebbe implementarlo. Passerò l'invocazione di quel messaggio a quell'oggetto.

In Cocoa, ancora una volta, qualsiasi classe può implementare il metodo -forwardInvocation:. Se un messaggio viene inviato a un oggetto che non lo implementa, viene chiamato il metodo -forwardInvocation: dell'oggetto, e l'oggetto può decidere di passare l'invocazione a un altro oggetto. Tale oggetto potrebbe essere il suo delegato, oppure potrebbe essere un gestore di errori a livello di sistema o qualsiasi altra cosa. NSProxy utilizza questo per implementare tutti i metodi - passa semplicemente l'invocazione sul suo oggetto principale.

Si noti che con l'inoltro non esiste un'interfaccia di delegato definita; il messaggio è appena passato a un altro oggetto. Un altro punto in cui vedete quello che chiamerei forward è quando un oggetto contiene un altro oggetto che usa per implementare un'interfaccia. Tutti i messaggi a quell'interfaccia vengono semplicemente inoltrati all'oggetto contenuto, che esegue tutto il lavoro.

10

Inoltro è un po 'come "l'ereditarietà tramite contenimento" o "l'ereditarietà dell'implementazione nel modo più difficile".

tipica ereditarietà dell'implementazione:

class Base 
{ 
public: 
    void baseFn() { } 
}; 

class Derived : public Base 
{ 
public: 
    void derivedFn() { } 
}; 

Ora, un'istanza di Derivato ha un metodo baseFn(). Questo è un modo di condividere l'implementazione tra diverse classi.

Inoltro assomiglia a questo:

class Contained 
{ 
public: 
    void containedFn() { } 
}; 

class Thing 
{ 
public: 
    void thingFn() { } 
    void containedFn() { mContained.containedFn(); } 
private: 
    Contained mContained; 
}; 

Si potrebbe avere anche realizzato che con l'ereditarietà privata.

La delega è un caso speciale di inoltro, in cui alla "cosa da inoltrare" è un'interfaccia stessa.

class Delegate 
{ 
public: 
    virtual void doDelegateAction() = 0; 
}; 

class DelegateA : public Delegate 
{ 
    virtual void doDelegateAction() { } 
}; 

class DelegateB : public Delegate 
{ 
    virtual void doDelegateAction() { } 
}; 

class Thing 
{ 
public: 
    void Thing (Delegate * delegate) { mDelegate = delegate; } 
    void thingFn() { } 
    void containedFn() { if (mDelegate) mDelegate->doDelegateAction(); } 
private: 
    Delegate * mDelegate; // Note, we don't own this memory, buyer beware. 
}; 

Ora, è possibile scambiare l'attuazione della delega in fase di esecuzione, mentre in spedizioni non si può (e si potrebbe non si vuole, che è il motivo per cui si dovrebbe farlo).

Se questo risponde alla domanda sbagliata, fammi sapere in un commento e rimuoveremo la risposta.

+0

Non penso che 'unique_ptr' sia copiabile. –

+0

Quindi stai dicendo che l'inoltro richiede che la classe abbia l'oggetto delegato contenuto nella classe, ma la delega può facoltativamente utilizzare oggetti istanziati al di fuori della classe? La distinzione tra i due non è ancora del tutto chiara. – vette982

+0

@ vette982 Scusate, ho omesso una chiave peice nel mio ultimo esempio ... Modifica in arrivo a breve. –

7

si deve prima definire due termini:

  • mittente: the object that sends a message/task to another object(the receiver)
  • ricevitore: the object that receives a message/task from the sender

La differenza tra spedizioni e delegazione è che in forwa numerothe receiver acts in its own context mentre in delegathe receiver acts on the behalf of the sender.

Ecco una grande metafora da questo blog post:

delegazione e inoltro sono entrambi molto simili. Una metafora che potrebbe aiutarli a distinguerli è pensare di ricevere un'e-mail che ti chiede di donare dei soldi a una degna organizzazione benefica.

  • Se avanti l'e-mail ad un amico, e l'amico dona i soldi, l'amico è donare il proprio denaro e ottenere la propria ricevuta fiscale.
  • Se si delegato risponde al proprio commercialista, il contabile dona il proprio denaro in beneficenza e si riceve la ricevuta fiscale.