stringtranslate.com

Delegación (programación orientada a objetos)

En programación orientada a objetos , la delegación se refiere a evaluar 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 explícitamente, pasando el objeto emisor al objeto receptor, lo que se puede realizar en cualquier lenguaje orientado a objetos ; o implícitamente, por las reglas de búsqueda de miembros del idioma, lo que requiere soporte de idioma para la característica. La delegación implícita es el método fundamental para la reutilización del comportamiento en la programación basada en prototipos , correspondiente 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 principales mutables que se utilizan en la búsqueda de métodos en autollamadas, y JavaScript ; consulte delegación de JavaScript .

El término delegación también se utiliza libremente para otras relaciones entre objetos; consulte delegación (programación) para obtener más información. Conceptos que frecuentemente se confunden son simplemente el uso de otro objeto, más precisamente denominado consulta o agregación ; y evaluar un miembro en un objeto evaluando el miembro correspondiente en otro objeto, especialmente en el contexto del objeto receptor, lo que se conoce más precisamente como reenvío (cuando un objeto contenedor no se pasa 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 usa libremente para consulta o reenvío.

Descripción general

Lieberman definió 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 en su artículo de 1986 "Uso de objetos prototípicos para implementar un comportamiento compartido en sistemas orientados a objetos".

La delegación depende del enlace dinámico , ya que requiere que una llamada a un método determinado pueda invocar diferentes segmentos de código en tiempo de ejecución [ cita requerida ] . Se utiliza en macOS (y su predecesor NeXTStep ) como una forma de personalizar el comportamiento de los componentes del programa. [3] Permite implementaciones como el uso de una única clase proporcionada por el sistema operativo para administrar Windows, 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 no guardados representados por el contenido de la ventana.

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

... los mensajes enviados a la variable self(o this) en el padre "volverán" al objeto que recibió originalmente 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 está adjunta a un objeto), sino que en el momento de la evaluación , está vinculada al original. objeto.

Se ha argumentado que en algunos casos puede preferirse la delegación a la herencia para hacer 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 modelo alternativo a la herencia. La relación precisa entre delegación y herencia es complicada; algunos autores los consideran equivalentes, o uno como un caso especial del otro. [6]

Soporte de idiomas para la delegación

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

La delegación tiene la ventaja de que puede tener lugar en tiempo de ejecución y afectar sólo 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 se puede verificar 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 :

class  A { void foo () { // "esto" también se conoce con los nombres "actual", "yo" y "yo" en otros idiomas . bar (); }        barra vacía () { imprimir ( "a.bar" ); } }    clase  B { delegado privado A a ; // enlace de delegación       público B ( A a ) { este . una = una ; }        vacío foo () { a . foo (); // llama a foo() en la instancia a }      barra vacía () { imprimir ( "b.bar" ); } }    a = nueva A (); b = nuevo B ( a ); // establecer delegación entre dos objetos       

Al llamar, se b.foo()imprimirá b.bar , ya que thisse refiere al objeto receptor originalb , dentro del contexto de a. La ambigüedad resultante thisse denomina esquizofrenia objetal .

Al traducir el parámetro implícito thisen un parámetro explícito, la llamada (en B, con aun delegado) a.foo()se traduce en A.foo(b), utilizando el tipo de apara la resolución del método, pero el objeto de delegación 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 () { esto . bar (); }       barra vacía () { imprimir ( "A.barra" ); } }    clase  B extiende A { public B () {}       vacío foo () { super . foo (); // llama a foo() de la superclase (A) }      barra vacía () { imprimir ( "B.barra" ); } }    b = nuevo B ();   

Llamar b.foo()resultará en B.bar . En este caso, thisno es ambiguo: hay un único objeto, by 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 existen 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 { delegationlink D d ; }      

Esto requiere reglas adicionales para la búsqueda de métodos, ya que ahora hay potencialmente dos métodos que pueden denominarse 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 tanto, sienta las bases para otras construcciones del lenguaje. En particular, los lenguajes de programación orientados a roles han estado utilizando la delegación, pero especialmente los más antiguos utilizaron la agregación mientras afirmaban utilizar la delegación. Esto no debe considerarse una trampa, sino simplemente las definiciones plurales de lo que significa delegación (como se describe 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 encuentran habitaciones de hotel baratas) puedan utilizar una entidad compartida utilizando la delegación para compartir los mejores resultados y la funcionalidad general reutilizable.

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

Ver 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 son "reenvío" y "delegación", como se utilizan en este artículo.

Referencias

  1. ^ Gamma y col. 1995, "Delegación", págs. 20 y 21.
  2. ^ Beck 1997, "Delegación", págs. 64–69.
  3. ^ Manzana (20 de agosto de 2009). "Guía de fundamentos del cacao: delegados y fuentes de datos". Conexión de desarrollador de Apple . Consultado el 11 de septiembre de 2009 .
  4. ^ "Clases y prototipos que se cruzan". Perspectivas de la informática de sistemas: Quinta Conferencia Internacional en Memoria de Andrei Ershov, PSI 2003, Akademgorodok, Novosibirsk, Rusia, 9 al 12 de julio de 2003, artículos revisados . pag. 38.
  5. ^ [1] Trygve Reenskaug , Departamento de Informática, Universidad de Oslo, "El caso del código legible" (2007)
  6. ^ Stein, Lynn Andrea. Delegar es herencia . OOPSLA '87 Actas de la conferencia 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 conferencias sobre informática. vol. 1628. Saltador. 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 . Este artículo propone la herencia basada en objetos (también conocida como delegación) como complemento a la composición de objetos puramente basada en reenvío. Presenta una integración segura de tipos de delegación en un modelo de objetos basado en clases y 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 los componentes.{{cite book}}: Mantenimiento CS1: bot: estado de la URL original desconocido ( enlace )

enlaces externos