stringtranslate.com

Delegación (programación orientada a objetos)

En la programación orientada a objetos , la delegación se refiere a la evaluación de un miembro ( propiedad o método ) de un objeto (el receptor) en el contexto de otro objeto original (el remitente). La delegación se puede realizar de forma explícita, al pasar las responsabilidades del objeto emisor al objeto receptor, lo que se puede hacer en cualquier lenguaje orientado a objetos ; o de forma implícita, mediante las reglas de búsqueda de miembros del lenguaje, lo que requiere que el lenguaje admita la característica. La delegación implícita es el método fundamental para la reutilización de comportamientos en la programación basada en prototipos , que corresponde a la herencia en la programación basada en clases . Los lenguajes más conocidos que admiten la delegación a nivel de lenguaje son Self , que incorpora la noción de delegación a través de su noción de ranuras de padres mutables que se utilizan en la búsqueda de métodos en las llamadas self, y JavaScript ; consulte Delegación de JavaScript .

El término delegación también se utiliza de forma imprecisa para varias otras relaciones entre objetos; consulte delegación (programación) para obtener más información. Los conceptos que se confunden con frecuencia son simplemente usar otro objeto, más precisamente denominado consulta o agregación ; y evaluar un miembro en un objeto evaluando el miembro correspondiente en otro objeto, en particular en el contexto del objeto receptor, lo que se conoce con más precisión como reenvío (cuando un objeto envolvente no se pasa a sí mismo al objeto envuelto). [1] [2] [a] El patrón de delegación es un patrón de diseño de software para implementar la delegación, aunque este término también se utiliza de forma imprecisa para consulta o reenvío.

Descripción general

Este sentido de delegación como característica del lenguaje de programación que hace uso de las reglas de búsqueda de métodos para enviar las llamadas autollamadas fue definido por Lieberman en su artículo de 1986 "Uso de objetos prototípicos para implementar comportamiento compartido en sistemas orientados a objetos".

La delegación depende de la vinculación dinámica , ya que requiere que una llamada de método determinada pueda invocar diferentes segmentos de código en tiempo de ejecución [ cita requerida ] . Se utiliza en macOS (y su predecesor NeXTStep ) como un medio para personalizar el comportamiento de los componentes del programa. [3] Permite implementaciones como hacer uso de una sola clase proporcionada por el sistema operativo para administrar ventanas, porque la clase toma un delegado que es específico del programa y puede anular el comportamiento predeterminado según sea necesario. Por ejemplo, cuando el usuario hace clic en el cuadro de cierre, el administrador de ventanas envía al delegado una llamada windowShouldClose: y el delegado puede retrasar el cierre de la ventana, si hay datos sin guardar representados por el contenido de la ventana.

La delegación se puede caracterizar (y distinguir del reenvío ) como una vinculación tardía de uno mismo : [4]

... los mensajes enviados a la variable self(o this) en el padre "regresarán" al objeto que originalmente recibió el mensaje.

Es decir, la selfdefinición de un método en el objeto receptor no está vinculada estáticamente a ese objeto en el momento de la definición (como en el momento de la compilación o cuando la función se adjunta a un objeto), sino que, en el momento de la evaluación , está vinculada al objeto original .

Se ha argumentado que, en algunos casos, la delegación puede ser preferible a la herencia para que el código del programa sea más legible y comprensible. [5] A pesar de que la delegación explícita está bastante extendida, relativamente pocos lenguajes de programación importantes implementan la delegación como un modelo alternativo a la herencia. La relación precisa entre la delegación y la herencia es complicada; algunos autores las consideran equivalentes, o una es un caso especial de la otra. [6]

Soporte de idiomas para delegación

En los lenguajes que admiten la delegación mediante reglas de búsqueda de métodos, el envío de métodos se define de la misma manera que para los métodos virtuales en la herencia: siempre se elige el método más específico durante la búsqueda de métodos. Por lo tanto, la entidad receptora original es la que inicia la búsqueda de métodos, aunque haya pasado el control a otro objeto (a través de un vínculo de delegación, no de una referencia de objeto).

La delegación tiene la ventaja de que puede tener lugar en tiempo de ejecución y afectar solo a un subconjunto de entidades de algún tipo e incluso puede eliminarse en tiempo de ejecución. La herencia, por el contrario, normalmente se dirige al tipo en lugar de a las instancias, y está restringida al tiempo de compilación. Por otro lado, la herencia puede comprobarse estáticamente, mientras que la delegación generalmente no puede hacerlo sin genéricos (aunque una versión restringida de la delegación puede ser estáticamente segura [7] ). La delegación puede denominarse "herencia en tiempo de ejecución para objetos específicos".

A continuación se muestra un ejemplo de pseudocódigo en un lenguaje similar a C# / Java :

clase  A { void foo () { // "this" también conocido bajo los nombres "current", "me" y "self" en otros idiomas this . bar (); }        void bar () { print ( "a.bar" ); } }    clase  B { delegado privado A a ; // enlace de delegación       público B ( A a ) { este . a = a ; }        void foo () { a.foo (); // llamar a foo() en la instancia a }      void bar () { print ( "b.bar" ); } }    a = new A (); b = new B ( a ); //establecer delegación entre dos objetos       

La llamada b.foo()dará como resultado la impresión de b.barthis , ya que hace referencia al objeto receptor originalb , , dentro del contexto de a. La ambigüedad resultante de thisse conoce como objeto esquizofrenia .

Al traducir lo implícito thisen un parámetro explícito, la llamada (en B, con aun delegado) a.foo()se traduce a A.foo(b), utilizando el tipo de apara la resolución del método, pero el objeto delegante bpara el thisargumento.

Usando herencia, el código análogo (usando letras mayúsculas para enfatizar que la resolución se basa en clases, no en objetos) es:

clase  A { void foo ( ) { este.bar () ; }       void bar () { print ( "A.bar" ); } }    la clase  B extiende A { public B () {}       void foo () { super.foo (); // llamar a foo() de la superclase ( A ) }      void bar () { print ( "B.bar" ); } }    b = nuevo B ();   

La llamada b.foo()dará como resultado B.bar . En este caso, thisno hay ambigüedades: hay un único objeto, b, y this.bar()se resuelve en el método de la subclase.

Los lenguajes de programación en general no admiten esta forma inusual de delegación como concepto de lenguaje, pero hay algunas excepciones [ cita requerida ] .

Herencia dual

Si el lenguaje admite tanto la delegación como la herencia, se puede realizar una herencia dual utilizando ambos mecanismos al mismo tiempo, como en

la clase  C extiende A { enlace de delegación D d ; }      

Esto requiere reglas adicionales para la búsqueda de métodos, ya que ahora hay potencialmente dos métodos que pueden indicarse como los más específicos (debido a las dos rutas de búsqueda).

Áreas relacionadas

La delegación puede describirse como un mecanismo de bajo nivel para compartir código y datos entre entidades. Por lo tanto, sienta las bases para otras construcciones del lenguaje. Cabe destacar que los lenguajes de programación orientados a roles han estado utilizando la delegación, pero especialmente los más antiguos usaban de hecho la agregación mientras afirmaban usar la delegación. Esto no debe considerarse una trampa, sino simplemente las definiciones plurales de lo que significa la delegación (como se describió anteriormente).

Más recientemente, también se ha trabajado en la distribución de la delegación, de modo que, por ejemplo, los clientes de un motor de búsqueda (que busca habitaciones de hotel baratas) puedan usar una entidad compartida mediante delegación para compartir los mejores resultados y una funcionalidad general reutilizable.

Ernst y Lorenz también sugirieron la delegación para la resolución de problemas en programación orientada a aspectos en 2003.

Véase también

Distinguir:

Notas

  1. ^ Beck 1997 utiliza los términos "delegación simple" para cuando el objeto receptor no tiene acceso al objeto emisor, y "autodelegación" para cuando el objeto receptor sí tiene acceso al objeto emisor; en lenguaje moderno estos son "reenvío" y "delegación", como se utilizan en este artículo.

Referencias

  1. ^ Gamma et al. 1995, "Delegación", págs. 20-21.
  2. ^ Beck 1997, "Delegación", págs. 64-69.
  3. ^ Apple (20 de agosto de 2009). "Guía de conceptos básicos de Cocoa: delegados y fuentes de datos". Apple Developer Connection . Consultado el 11 de septiembre de 2009 .
  4. ^ "Intersección de clases y prototipos". Perspectivas de la informática de sistemas: 5.ª conferencia internacional en memoria de Andrei Ershov, PSI 2003, Akademgorodok, Novosibirsk, Rusia, 9-12 de julio de 2003, Documentos revisados , pág. 38.
  5. ^ [1] Trygve Reenskaug , Departamento de Informática, Universidad de Oslo, "El caso del código legible" (2007)
  6. ^ Stein, Lynn Andrea. La delegación es herencia . Actas de la conferencia OOPSLA '87 sobre sistemas, lenguajes y aplicaciones de programación orientada a objetos. págs. 138-146. doi :10.1145/38807.38820.
  7. ^ Günter Kniesel (19 de noviembre de 1999). "Delegación de tipo seguro para la adaptación de componentes en tiempo de ejecución". ECOOP' 99 — Programación orientada a objetos . Apuntes de clase en informática. Vol. 1628. Springer. págs. 351–366. CiteSeerX 10.1.1.33.7584 . doi :10.1007/3-540-48743-3_16. ISBN .  978-3-540-66156-6. Archivado desde el original el 4 de marzo de 2015. Consultado el 4 de marzo de 2015. En este artículo se propone la herencia basada en objetos (también conocida como delegación) como complemento a la composición de objetos basada puramente en reenvío. Se presenta una integración de delegación con seguridad de tipos en un modelo de objetos basado en clases y se muestra cómo supera los problemas que enfrenta la interacción de componentes basada en reenvío, cómo admite la extensibilidad independiente de los componentes y la adaptación dinámica e imprevista de componentes.{{cite book}}: CS1 maint: bot: estado de URL original desconocido ( enlace )

Enlaces externos