2011-10-19 12 views
15

¿Podría alguien explicar la diferencia entre el reenvío y la delegación? Parecen similares, pero no he podido encontrar una buena definición de reenvío, así que no estoy seguro de entender realmente.En OOP, ¿qué es el reenvío y cómo es diferente de la delegación?

+0

No estoy seguro de por qué esto votó en contra ... Parece una pregunta útil, aunque podría necesitar un poco más de elaboración. Desafortunadamente, podríamos estar en un Catch-22 aquí. Trataré de dar una respuesta, y el interlocutor puede decirme si entiendo correctamente. –

Respuesta

2

Son ideas similares en que un objeto depende de otro para obtener ayuda. Así es como pienso en las dos ideas dado mi fuerte sesgo Objective-C:

delegación: Se debe tomar una decisión, pero no quiero hacerlo. Dejaré que mi delegado maneje eso.

En Cocoa, por ejemplo, NSTableView usa un delegado para personalizar el comportamiento de la tabla. La delegación proporciona una forma de personalizar un objeto permitiendo que otro objeto, el delegado, proporcione la personalización. Continuando con el ejemplo, el delegado de una vista de tabla implementa una interfaz NSTableViewDelegate que la tabla usa para hablar con su delegado.

reenvío: Alguien me acaba de enviar un mensaje que no entiendo, pero conozco otro objeto que podría implementarlo. Pasaré la invocación de ese mensaje a ese objeto.

En Cocoa, de nuevo, cualquier clase puede implementar el método -forwardInvocation:. Si se envía un mensaje a un objeto que no lo implementa, se llama al método invocación-adelante de ese objeto, y el objeto puede decidir pasar la invocación a otro objeto. Ese objeto podría ser su delegado, o podría ser algún controlador de errores en todo el sistema, o lo que sea. NSProxy usa esto para parecer implementar todos los métodos - simplemente pasa la invocación a su objeto maestro.

Tenga en cuenta que con el reenvío, no hay una interfaz de delegado definida; el mensaje acaba de pasar a otro objeto. Otro lugar donde puede ver lo que yo llamaría reenviar es cuando un objeto contiene otro objeto que usa para implementar alguna interfaz. Cualquier mensaje a esa interfaz solo se reenvía al objeto contenido, que hace todo el trabajo.

10

El reenvío es algo así como "herencia a través de la contención" o "herencia de implementación de la manera difícil".

Típica herencia de implementación:

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

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

Ahora, una instancia de Derivado tiene un método baseFn(). Esta es una forma de compartir la implementación entre diferentes clases.

Forwarding se ve así:

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

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

También podría haber implementado que con la herencia privada.

La delegación es un caso especial de reenvío, donde en el "elemento a reenviar" se encuentra una interfaz.

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. 
}; 

Ahora, usted puede intercambiar la aplicación del delegado en tiempo de ejecución, mientras que en el envío no se puede (y es posible que no desea, por lo que lo haría).

Si responde la pregunta incorrecta, házmelo saber en un comentario y eliminaré la respuesta.

+0

No creo que 'unique_ptr' se pueda copiar. –

+0

Entonces, ¿está diciendo que el reenvío requiere que la clase tenga el objeto delegado contenido dentro de la clase, pero la delegación puede usar opcionalmente objetos instanciados fuera de la clase? La distinción entre los dos todavía no está completamente clara. – vette982

+0

@ vette982 Disculpa, omití una pieza clave en mi último ejemplo ... Editar próximamente. –

7

primero definir dos términos Repasemos:

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

La diferencia entre expedición y delegación es que en forwa rdingthe receiver acts in its own context mientras que en delegaciónthe receiver acts on the behalf of the sender.

Aquí es una gran metáfora de esta blog post:

Delegación y expedición son muy similares. Una metáfora que podría ayudar a distinguirlos es pensar en recibir un correo electrónico pidiéndole que done algo de dinero a una caridad digna.

  • Si hacia adelante el correo electrónico a un amigo, y el amigo dona dinero, el amigo es donar su propio dinero y conseguir su propio recibo de impuestos.
  • Si delegue respondiendo a su contador, el contador dona su dinero a la organización benéfica y usted recibe el recibo de impuestos.
Cuestiones relacionadas