Patrón de delegación

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 15 de enero de 2015; las comprobaciones requieren 14 ediciones .
Delegación
delegación
Descrito en Patrones de diseño No

La delegación es un  patrón de diseño básico en el que un objeto expresa externamente algún comportamiento , pero en realidad transfiere la responsabilidad de realizar este comportamiento a un objeto relacionado. El patrón de delegación es la abstracción fundamental sobre la cual se implementan los otros patrones: composición (también llamada agregación), mixins y aspectos .

Ventajas

La capacidad de cambiar el comportamiento de una instancia particular de un objeto en lugar de crear una nueva clase a través de la herencia.

Contras

Este patrón generalmente dificulta la optimización de la velocidad a favor de una pureza de abstracción mejorada.

Aplicabilidad

Java

Si bien la delegación no es compatible con el lenguaje Java, es compatible con muchos entornos de desarrollo [1] .

Ejemplos

Java

Un ejemplo simple

En este ejemplo de Java , la clase Btiene un método auxiliar que pasa métodos al . La clase pretende tener atributos de clase . foo()bar()ABA

Texto fuente en java clase A { void foo () { Sistema . fuera _ println ( "A: metodo foo() llamado" ); } barra vacía () { Sistema . fuera _ println ( "A: barra de método() llamada" ); } } class B { // Crea un objeto cuyos métodos delegarán el comportamiento. A a = nuevo A (); vacío foo () { un . foo (); } barra vacía () { a . barra (); } } public class Main { public static void main ( String [] args ) { B b = new B (); segundo _ foo (); segundo _ barra (); } } Ejemplo complejo

Usando interfaces , la delegación se puede hacer de una manera más flexible y segura . En este ejemplo, la clase Cpuede delegar Aen B. La clase Ctiene métodos para cambiar entre clases Ay B. Incluir la extensión implements mejora la seguridad de tipos porque cada clase debe implementar los métodos en la interfaz. La principal desventaja es más código.

Tomemos un ejemplo. Suponga que necesita implementar un temporizador de tal manera que se llame a alguna función después de una cierta cantidad de tiempo. El programador de temporizadores quiere proporcionar una asignación de función a los usuarios de su clase (otros programadores).

Texto fuente en java /** * La interfaz describe la acción que se llamará cuando ocurra el evento * del temporizador. */ interfaz TimerAction { void onTime (); } class WakeUpAction implementa TimerAction { @Override public void onTime () { System . fuera _ println ( "¡Hora de levantarse!" ); } } class ChickenIsReadyAction implementa TimerAction { @Override public void onTime () { System . fuera _ println ( "¡El pollo está listo!" ); } } /** * Clase de temporizador. Bajo ciertas condiciones, se llama a TimerAction. */ class Timer { acción TimerAction ; /** * Una función que el programador llama para configurar la hora. */ void ejecutar () { if ( isTime ()) { acción . a la hora (); } } /** * Alguna función que se ocupa de todo el trabajo del tiempo. Su * implementación no es interesante en este contexto. * * @return */ private boolean isTime () { return true ; } public static void main ( String [] args ) { sistema _ fuera _ println ( "Ingrese el tipo de acción:" ); Escáner escáner = nuevo Escáner ( System . in ); Cadena actionType = escáner . siguienteLinea (); Temporizador temporizador = nuevo temporizador (); if ( actionType . equalsIgnoreCase ( "establecer temporizador de activación" )) { timer . acción = nueva WakeUpAction (); } else if ( actionType . equalsIgnoreCase ( "establecer temporizador de pollo" )) { temporizador . action = new ChickenIsReadyAction (); } temporizador _ ejecutar (); }

C++

Ejemplo complejo

Este ejemplo es una versión C++ del ejemplo complejo de Java anterior. Dado que C++ no tiene una construcción de interfaz, la clase totalmente abstracta desempeña el mismo papel . Las ventajas y desventajas son básicamente las mismas que en el ejemplo de Java.

Texto fuente en c++ #incluir <iostream> clase I { público : vacío virtual f () = 0 ; vacío virtual g () = 0 ; }; clase A : público I { público : void f () { std :: cout << "A: llamando al método f()" << std :: endl ; } void g () { std :: cout << "A: llamar al método g()" << std :: endl ; } }; clase B : público I { público : void f () { std :: cout << "B: llamar al método f()" << std :: endl ; } void g () { std :: cout << "B: llamar al método g()" << std :: endl ; } }; clase C : público I { público : // Constructor C () : m_i ( nueva A () ) { } // Destructor virtual ~ C () { eliminar m_i ; } vacío f () { m_i -> f (); } vacío g () { m_i -> g (); } // Con estos métodos cambiamos el campo-objeto, cuyos métodos delegaremos void a A () { eliminar m_i ; m_i = nuevoA ( ); } vacío toB () { eliminar m_i ; m_i = nueva B (); } privado : // Declaramos un objeto cuyos métodos delegaremos I * m_i ; }; int principal () { C c ; do . f (); do . gramo (); do . toB (); do . f (); do . gramo (); devolver 0 ; } /* Salida: A: llamar al método f() A: llamar al método g() B: llamar al método f() B: llamar al método g() */

C#

Texto fuente en C# Patrones de espacio de nombres { interfaz I { void f (); vacío ( ); } clase A : I { public void f () { System . consola _ WriteLine ( "A: llamando al método f()" ); } public void g () { Sistema . consola _ WriteLine ( "A: llamando al método g()" ); } } clase B : I { public void f () { System . consola _ WriteLine ( "B: llamando al método f()" ); } public void g () { Sistema . consola _ WriteLine ( "B: llamando a g()" ); } } class C : I { // Crear un objeto cuyos métodos delegaremos I i = new A (); vacío público f () { yo . f (); } public void g () { i . gramo (); } // Con estos métodos cambiamos el campo-objeto, cuyos métodos delegaremos public void a A () { i = new A (); } public void toB () { i = new B (); } } class DelegatePattern { static void Main ( string [] args ) { C c = new C (); do . f (); do . gramo (); do . toB (); do . f (); do . gramo (); sistema _ consola _ Clave de lectura (); } } } Ejemplo no trivial

Este es un ejemplo de un caso que se encuentra a menudo en la práctica. Hay una tarea para crear una clase para el almacenamiento de la lista de empleados. Los datos de cada empleado se almacenan en un objeto de la clase Empleado. Existe una clase estándar y preparada para almacenar una lista de objetos Employee. Ya ha implementado mecanismos para trabajar con la lista (por ejemplo, asignación de memoria, agregar y quitar de la lista). Heredar la clase de lista de empleados de la clase de lista de objetos no es aceptable aquí, porque obtendremos todos los métodos (incluso aquellos que no nos interesan). Además, tendremos que realizar casting de tipos en algunos casos. La forma más elegante de salir de este caso es delegar algunos de los métodos de la clase de lista de objetos a la clase de lista de empleados. En las reglas OOP, es mejor representar la lista de objetos con un método privado (privado) de la lista de empleados. En este caso, se puede acceder a la lista a través de un indexador.

Texto fuente en C# utilizando el sistema ; usando System.Collections.Generic ; usando System.Linq ; usando System.Text ; namespace Employees { /// <summary> /// Clase para almacenar datos de empleados. /// </summary> class Empleado { private string name ; departamento privado de cuerdas ; empleado público ( cadena nombre , cadena departamento ) { this . nombre = nombre ; esto _ departamento = departamento ; } /// <resumen> /// Nombre del empleado. /// </summary> public string Nombre { get { return this . nombre ; } } /// <resumen> /// Departamento de trabajo. /// </summary> public string Department { get { return this . departamento ; } } } /// <summary> /// Clase para almacenar una lista de empleados. /// </summary> class EmployeesList { lista privada < Empleado > empleados = nueva Lista < Empleado >(); /// <summary> /// Propiedad para obtener y escribir un empleado por índice. /// </summary> /// <param name="index">Índice de empleados.</param> /// <returns>Employee.</returns> public Employee this [ int index ] { get { return employee [ índice ]; } set { empleados [ índice ] = valor ; } } /// <resumen> /// Añadir un nuevo empleado. /// </summary> /// <param name="empleado">Nuevo empleado.</param> public void Add ( Empleado empleado ) { empleados . Añadir ( empleado ); } /// <summary> /// Eliminación de un empleado existente. /// </summary> /// <param name="employee">El empleado a eliminar.</param> public void Eliminar ( Empleado empleado ) { empleados . Quitar ( empleado ); } /// <summary> /// Búsqueda secuencial de un empleado por nombre. /// </summary> /// <param name="name">Nombre del empleado.</param> /// <param name="offset">Posición desde la que empezar a buscar.</param> // / < devuelve>Índice de empleados.</retornos> public int GetIndexOfEmployeeByName ( string name , int offset = 0 ) { for ( int i = offset ; i < empleados . Contar ; i ++) { if ( empleados [ i ]. Nombre == nombre ) { retornar i ; } } retorno - 1 ; } } class Program { static void Main ( string [] args ) { //Crear una lista de empleados y agregarle entradas EmployeesList empList = new EmployeesList (); empList . Agregar ( nuevo empleado ( "Shlensky Dmitry" , "estudio web" )); empList . Agregar ( nuevo Empleado ( "Kusy Nazar" , "estudio web" )); empList . Agregar ( nuevo empleado ( "Urraca Orest" , "estudio web" )); //Buscar al empleado Kusyi Nazar y mostrar el resultado al buscar desde el principio y desde la 2ª posición Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); consola _ WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Buscar y eliminar empleado Soroka Orestes empList . Remove ( empList [ empList . GetIndexOfEmployeeByName ( "Urraca Orestes" )]); } } } Texto fuente en C# 2 utilizando el sistema ; usando System.Collections.Generic ; usando System.Linq ; usando System.Text ; namespace Employees { /// <summary> /// Clase para almacenar datos de empleados. /// </summary> class Empleado { private string name ; departamento privado de cuerdas ; empleado público ( cadena nombre , cadena departamento ) { this . nombre = nombre ; esto _ departamento = departamento ; } /// <resumen> /// Nombre del empleado. /// </summary> public string Nombre { get { return this . nombre ; } } /// <resumen> /// Departamento de trabajo. /// </summary> public string Department { get { return this . departamento ; } } } /// <summary> /// Clase para almacenar una lista de empleados. /// </summary> class EmployeesList { lista privada < Empleado > empleados = nueva Lista < Empleado >(); /// <summary> /// Propiedad para obtener y escribir un empleado por índice. /// </summary> /// <param name="index">Índice de empleados.</param> /// <returns>Employee.</returns> public Employee this [ int index ] { get { return employee [ índice ]; } set { empleados [ índice ] = valor ; } } /// <summary> /// Propiedad para obtener y escribir un empleado por nombre. /// </summary> /// <param name="name">Nombre del empleado.</param> /// <returns>El primer empleado cuyo nombre coincidió o fue nulo</returns> public Employee this [ string name ] { obtener { foreach ( artículo de empleado en empleados ) { si ( artículo . Nombre == nombre ) devolver artículo ; } devuelve nulo ; } } /// <resumen> /// Añadir un nuevo empleado. /// </summary> /// <param name="empleado">Nuevo empleado.</param> public void Add ( Empleado empleado ) { empleados . Añadir ( empleado ); } /// <summary> /// Eliminación de un empleado existente. /// </summary> /// <param name="employee">El empleado a eliminar.</param> public void Eliminar ( Empleado empleado ) { empleados . Quitar ( empleado ); } /// <summary> /// Búsqueda secuencial de un empleado por nombre. /// </summary> /// <param name="name">Nombre del empleado.</param> /// <param name="offset">Posición desde la que empezar a buscar.</param> // / < devuelve>Índice de empleados.</retornos> public int GetIndexOfEmployeeByName ( string name , int offset ) { int index = - 1 ; for ( int i = compensación ; i < empleados . Cuenta ; i ++) { if ( empleados [ i ]. Nombre == nombre ) { index = i ; romper ; } } índice de retorno ; } /// <summary> /// Búsqueda secuencial de un empleado por nombre. /// </summary> /// <param name="name">Nombre del empleado.</param> /// <returns>Índice de empleados.</returns> public int GetIndexOfEmployeeByName ( string name ) { return GetIndexOfEmployeeByName ( name , 0 ); } } class Program { static void Main ( string [] args ) { //Crear una lista de empleados y agregarle entradas EmployeesList empList = new EmployeesList (); empList . Agregar ( nuevo empleado ( "Shlensky Dmitry" , "estudio web" )); empList . Agregar ( nuevo Empleado ( "Kusy Nazar" , "estudio web" )); empList . Agregar ( nuevo empleado ( "Urraca Orest" , "estudio web" )); //Buscar al empleado Kusyi Nazar y mostrar el resultado al buscar desde el principio y desde la 2ª posición Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()); consola _ WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()); //Buscar y eliminar empleado Soroka Orestes empList . Quitar ( empList [ "Urraca Orestes" ]); } } }

Objective-C 2.0

Un ejemplo simple Código fuente de Objective-C enumeración { GLEngineChangeView }; @interfaz GLEngine  : NSObject { id_delegado ; _ BOOL_event [ NÚMERO ] ; } - ( id ) delegado ; - ( vacío ) setDelegate: ( id ) delegado ; - ( vacío ) changeView: ( GLView * ) vista ; @final @protocolo GLEngineDelegate < NSObject > @opcional - ( BOOL ) motor : ( GLEngine * ) motor changeView : ( GLView * ) vista ; @final @interface GLEngine (interno) - ( vacío ) registrarseDelegado ; @final @implementationGLEngine _ - ( id ) delegado { volver _delegado ; } - ( vacío ) setDelegate: ( id ) delegado { _delegado = delegado ; [ auto registrarse Delegado ]; } - ( vacío ) changeView: ( GLView * ) vista { si ( _event [ GLEngineChangeView ]) { // solicitud de delegado if ([ _delegate engine : self changeView : view ]) { // usar vista modificada } más // la solicitud no fue procesada } // o usa la forma estándar } - ( vacío ) registrarseDelegado { if ([ _delegate responseToSelector : @selector ( motor : changeView :)]) { _event [ GLEngineChangeView ] = ; } } @final @interface MyGLEngineDelegate  : NSObject < GLEngineDelegate > { // } @final @implementationMyGLEngineDelegate _ - ( BOOL ) motor: ( Motor * ) motor changeView: ( GLView * ) vista { // cambiar vista } @final

ObjetoPascal

Un ejemplo simple Texto fuente en Object Pascal escribe IDelegateInterface = procedimiento de interfaz Método1 ; procedimiento Método2 ; fin ; TClassA = clase ( TInterfacedObject , IDelegateInterface ) procedimiento público Method1 ; procedimiento Método2 ; fin ; TClassB = clase ( TInterfacedObject , IDelegateInterface ) procedimiento público Method1 ; procedimiento Método2 ; fin ; TClassDel = clase ( TInterfacedObject , IDelegateInterface ) private FInterface : IDelegateInterface ; procedimiento público Método1 ; procedimiento Método2 ; procedimiento ToClassA ; procedimiento AClaseB ; fin ; implementación {TClaseA} procedimiento TClassA . método1 ; comenzar Writeln ( 'TClassA.Method1' ) ; fin ; procedimiento TClassA . método2 ; comenzar Writeln ( 'TClassA.Method2' ) ; fin ; {TClaseB} procedimiento TClassB . método1 ; comenzar Writeln ( 'TClassB.Method1' ) ; fin ; procedimiento TClassB . método2 ; comenzar Writeln ( 'TClassB.Method2' ) ; fin ; {TClassDel} procedimiento TClassDel . método1 ; comenzar FInterface . método1 ; fin ; procedimiento TClassDel . método2 ; comenzar FInterface . método2 ; fin ; procedimiento TClassDel . AClaseA ; comenzar FInterface := TClassA . crear ; fin ; procedimiento TClassDel . AClaseB ; comenzar FInterface := TClassB . crear ; fin ; Ejemplo no trivial

Este ejemplo es una versión de Object Pascal del ejemplo no trivial anterior.

Texto fuente en Object Pascal unidad UnidadEmpleadores ; interfaz utiliza Contnrs ; type // Clase para almacenar datos de empleados TEmployee = class private FName : string ; FDepartamento : cadena ; constructor público Crear ( Nombre , Departamento : cadena ) ; propiedad publicada Nombre : string read FName ; propiedad Departamento : la cadena lee FDepartamento ; fin ; // Clase para almacenar la lista de empleados TEmployeersList = class private // Objeto de la clase "lista de objetos" FEmployeersList : TObjectList ; function GetEmployee ( Índice : Integer ) : TEmployee ; procedimiento SetEmployee ( índice : entero ; valor const : TEmployee ) ; constructor público Crear ; destructor Destruir ; anular ; Función Añadir ( Empleado : TEmployee ) : Entero ; procedimiento Quitar ( Empleado : TEmployee ) ; función IndexEmployeeByName ( Nombre : cadena ; Desplazamiento : Entero = 0 ) : Entero ; propiedad Empleados [ Índice : Integer ] : TEmployee read GetEmployee write SetEmployee ; predeterminado ; fin ; implementación {empleado} constructor TEmpleado . Crear ( Nombre , Departamento : cadena ) ; comenzar FName := Nombre ; FDepartamento := Departamento ; fin ; { TemployeersList } constructor TEmployeersList . crear ; begin // Crea un objeto cuyos métodos delegaremos FEmployeersList := TObjectList . crear ; fin ; destructor TEmployeersList . destruir ; comenzar FEmployersList . Gratis ; heredado ; fin ; función TemployeersList . GetEmployee ( Índice : Integer ) : TEmployee ; comenzar el resultado : = FEmployeersList [ Índice ] como TEmployee ; fin ; procedimiento TEmployeersList . SetEmployee ( Índice : Entero ; Valor const : TEmployee ) ; comenzar FEmployeersList [ Índice ] := Valor ; fin ; función TemployeersList . IndexEmployeeByName ( Nombre : cadena ; Desplazamiento : Entero = 0 ) : Entero ; // Búsqueda secuencial de un empleado por nombre // A través del argumento Offset, puede establecer la posición desde la que buscar. // Si no se encuentra el empleado, devolverá un valor menor que cero (-1) var Index : Integer ; comenzar Resultado := - 1 ; // Asumiendo que no está en la lista de Index := FEmployeersList . Count - 1 downto Offset do if ( FEmployeeList [ Índice ] as TEmployee ) . Nombre = Nombre y luego comenzar Resultado : = Índice ; salida ; fin ; fin ; función TemployeersList . Añadir ( Empleado : TEmployee ) : Entero ; comenzar Resultado := FEmployeersList . Añadir ( Empleado ) ; fin ; procedimiento TEmployeersList . Quitar ( Empleado : TEmployee ) ; comenzar FEmployersList . Quitar ( Empleado ) ; fin ; fin _

Desafortunadamente, no todos los programadores usan el patrón de delegación. Por ejemplo, Borland (el desarrollador del entorno de programación Delphi ) en su biblioteca de clases estándar heredó la clase de lista de objetos TObjectList antes mencionada de la clase de lista de punteros TList . Esto causó descontento entre algunos programadores experimentados.

PHP5

Un ejemplo simple

Este ejemplo es una versión PHP del ejemplo simple de Java anterior.

código fuente PHP5 <?php clase A { public function f () { print "A: Llame al método f()<br />" ; } public function g () { print "A: Llamamos al método g()<br />" ; } } clase C { privado $_a ; public function __construct () { $this -> _a = new A ; } función pública f () { $esto -> _a -> f (); } función pública g () { $esto -> _a -> g (); } public function y () { print "C: llamar al método y()<br />" ; } } $obj = nueva C ; $objeto -> f (); $objeto -> g (); $objeto -> y (); ?> Ejemplo complejo

Este ejemplo es una versión PHP del ejemplo complejo de Java anterior.

código fuente PHP5 <?php // usar interfaz para tipo interfaz de seguridad I { public function f (); función pública g (); } la clase A implementa I { public function f () { print "A: Call f()<br />" ; } public function g () { print "A: Llamamos al método g()<br />" ; } } la clase B implementa I { public function f () { print "B: Call f()<br />" ; } public function g () { print "B: Llamar al método g()<br />" ; } } la clase C implementa I { private $_i ; // crea un objeto cuyos métodos serán delegados public function __construct () { $this -> _i = new A ; } // con estos metodos cambiamos el campo-objeto, cuyos metodos delegaremos public function aA () { $this -> _i = new A ; } public function toB () { $this -> _i = new B ; } // métodos delegados public function f () { $this -> _i -> f (); } función pública g () { $esto -> _i -> g (); } } $obj = nueva C ; $objeto -> f (); $objeto -> g (); $objeto -> toB (); $objeto -> f (); $objeto -> g (); ?> Ejemplo no trivial

Este ejemplo es una versión PHP del ejemplo no trivial anterior.

código fuente PHP5 <?php // clase para almacenar datos de empleados clase Empleado { privado $_nombre ; privado $_departamento ; public function __construct ( $nombre , $departamento ) { $esto -> _nombre = $nombre ; $esto -> _departamento = $departamento ; } public function getName () { return $this -> _name ; } public function obtenerDepartamento () { return $this -> _departamento ; } } // clase para almacenar una lista de objetos class ObjectList { privado $_objList ; public function __construct () { $this -> free (); } /** *¡para no aburrirse! */ public function free () { $this -> _objList = array (); } public function count () { return count ( $this -> _objList ); } función pública añadir ( $obj ) { array_push ( $this -> _objList , $obj ); } función pública remove ( $obj ) { $k = array_search ( $obj , $this -> _objList , true ); if ( $k !== false ) { unset ( $this -> _objList [ $k ] ); } } public function get ( $index ) { return $this -> _objList [ $index ]; } conjunto de funciones públicas ( $index , $obj ) { $this -> _objList [ $index ] = $obj ; } } // clase para almacenar empleados class EmployeeList { // objeto de la clase "lista de objetos" private $_employeersList ; public function __construct (){ // crea un objeto cuyos métodos delegaremos $this -> _employeersList = new ObjectList ; } función pública getEmployer ( $index ) { return $this -> _employeersList -> get ( $index ); } public function setEmployer ( $index , Employee $objEmployer ) { $this -> _employeersList -> set ( $index , $objEmployer ); } public function __destruct () { $this -> _employeersList -> free (); } public function add ( Empleado $objEmployer ) { $this -> _employeersList -> add ( $objEmployer ); } quitar función pública ( Empleado $objEmployer ) { $this -> _employeersList -> remove ( $objEmployer ); } // búsqueda secuencial de un empleado por nombre // a través del argumento $offset, puede establecer la posición desde la cual buscar. // si no se encuentra el empleado, devolverá un valor menor que cero (-1) public function getIndexByName ( $name , $offset = 0 ) { $result = - 1 ; // asume que no está en la lista $cnt = $this -> _employeersList -> count (); for ( $i = $compensación ; $i < $cnt ; $i ++ ) { if ( ! strcmp ( $nombre , $this -> _employeersList -> get ( $i ) -> getName () ) ) { $resultado = $i ; romper ; } } devuelve $resultado ; } } $obj1 = nuevo empleado ( "Tanasiychuk Stepan" , "estudio web" ); $obj2 = nuevo empleado ( "Kusy Nazar" , "estudio web" ); $obj3 = nuevo empleado ( "Urraca Orest" , "estudio web" ); $objList = new EmployeeList (); $objList -> agregar ( $obj1 ); $objList -> agregar ( $obj2 ); $objList -> agregar ( $obj3 ); echo "<pre>" ; print_r ( $objList ); echo "<hr>" ; $index = $objList -> getIndexByName ( "Kusy Nazar" ); $obj4 = $objList -> getEmployer ( $index ); imprimir_r ( $obj4 ) ; echo "<hr>" ; $objList -> setEmployer ( 2 , $obj4 ); print_r ( $objList ); eco "</pre>" ; ?>

Pitón

Un ejemplo simple

Código fuente en Python

#codificación: utf-8 #python 3 clase A : def f ( self ): print ( 'A: llamando al método f' ) def g ( self ): print ( 'A: llamando al método g' ) class C : def __init__ ( uno mismo ): uno mismo . A = A () def f ( self ): devuelve self . A._ _ f () def g ( auto ): devuelve auto . A._ _ gramo () do = do () do . f () #A: llama al método f c . g () #A: método de llamada g

JavaScript

Un ejemplo simple Código fuente JavaScript función A () { esto . f = function () { alert ( "A: llamando al método f()" ); }; esto _ g = función () { alerta ( "A: llamar al método g()" ); }; } función C () { var a = nueva A (); esto _ f = función () { un . f (); }; esto _ g = función () { un . gramo (); }; } var c = nueva C (); do . f (); // "A: llamando al método f()" c . gramo (); // "A: llamar al método g()" Ejemplo complejo Código fuente JavaScript función A () { esto . f = function () { alert ( "A: llamando al método f()" ); }; esto _ g = función () { alerta ( "A: llamar al método g()" ); }; } función B () { esto . f = función () { alerta ( "B: método de llamada f ()" ); }; esto _ g = función () { alerta ( "B: llamar al método g()" ); }; } function C () { // instanciar A y B una vez var a = new A (); varb = nueva B ( ); var cur = a ; // referencia al objeto actual con la implementación de métodos; predeterminado - A esto _ toA = función () { cur = a ; }; esto _ toB = función () { cur = b ; }; esto _ f = función () { cur . f (); }; esto _ g = función () { cur . gramo (); }; } var c = nueva C (); do . f (); // "A: llamando al método f()" c . gramo (); // "A: llamando al método g()" c . toB (); do . f (); // "B: llamando al método f()" c . gramo (); // "B: llamando al método g()" Ejemplo no trivial Código fuente JavaScript función Empleado ( nombre , departamento ) { this . getName = función () { devolver nombre ; }; esto _ getDepartamento = function () { return departamento ; }; esto _ toString = function () { // convertir a cadena para facilitar la depuración return "Empleado" + nombre + ", " + departamento ; }; } function ListaEmpleados () { var empleados = []; esto _ add = function () { // la función toma un número arbitrario de argumentos para ( var i = 0 , l = arguments . length ; i < l ; i ++ ) { if ( arguments [ i ]. constructor == Employee ) { empleados _ empujar ( argumentos [ i ]); } } }; esto _ set = function ( obj , índice ) { // tipo check if ( obj . constructor == Empleado ) { eliminar empleados [ índice ]; empleados [ índice ] = obj ; } }; esto _ remove = función ( obj ) { for ( var i = 0 , l = empleados . longitud ; i < l ; i ++ ) { if ( empleados [ i ] == obj ) { empleados . empalme ( i , 1 ); yo- ; _ yo - ; } } }; esto _ getByIndex = function ( num ) { devolver empleados [ num ]; }; esto _ getIndexByName = function ( name , offset ) { // búsqueda secuencial de un empleado por nombre // a través del argumento de compensación, puede establecer la posición desde la que buscar. (predeterminado 0) // si no se encuentra el empleado, devuelve -1 para ( var i = compensación || 0 , l = empleados . longitud ; i < l ; i ++ ) { if ( empleados [ i ]. getName () = = nombre ) devuelve i ; } retorno - 1 ; }; esto _ toString = function () { // convertir a cadena para una fácil depuración var ret = "" ; for ( var i = 0 , l = empleados . longitud ; i < l ; i ++ ) { ret += i + ": " + empleados [ i ] + "\n" ; } retorno ret ; }; } var o1 = nuevo empleado ( "Tanasiychuk Stepan" , "estudio web" ); var o2 = nuevo Empleado ( "Kusy Nazar" , "estudio web" ); var o3 = nuevo empleado ( "Urraca Orest" , "estudio web" ); var emps = nueva lista de empleados (); emp . suma ( o1 , o2 , o3 ); // puede agregar alertas una por una ( emps ); // "0: Empleado Tanasiychuk Stepan, estudio web // 1: Empleado Kusyi Nazar, estudio web // 2: Empleado Soroka Orest, estudio web" var obj4 = emps . getByIndex ( emps . getIndexByName ( "Kusy Nazar" ) ); // obtener un enlace a la alerta de empleado ( obj4 ); // "Empleado Kusyi Nazar, estudio web" emp . conjunto ( obj4 , 2 ); // en lugar del segundo empleado (desde cero), inserte la alerta obj4 ( emps ); // "0: Empleado Tanasiychuk Stepan, estudio web // 1: Empleado Kusyi Nazar, estudio web // 2: Empleado Kusyi Nazar, estudio web" emp . eliminar ( obj4 ); // elimina la alerta obj4 del empleado ( emps ); // "0: Empleado Tanasiychuk Stepan, estudio web"

VB.NET

Ejemplo complejo Código fuente en VB.NET Patrones de espacios de nombres Interfaz I Sub f () Sub g () Interfaz final Implementos Clase A I Public Sub f () Implementa I . Sistema f . consola _ WriteLine ( "A: llamando al método f()" ) End Sub Public Sub g () Implementa I . Sistema g . consola _ WriteLine ( "A: llamando al método g()" ) End Sub End Class Implementos Clase B I Public Sub f () Implementa I . Sistema f . consola _ WriteLine ( "B: llamando al método f()" ) End Sub Public Sub g () Implementa I . Sistema g . consola _ WriteLine ( "B: llamando al método g()" ) End Sub End Class Implementos Clase C I ' Crear un objeto cuyos métodos vamos a delegar Private i As I = New A () Public Sub f () Implementa i . fi._ _ _ f () Final Sub Public Sub g () Implementa i . g yo _ g () Fin sub 'Con estos métodos cambiamos el campo-objeto, cuyos métodos delegaremos Public Sub a A () i = New A () End Sub Public Sub toB () i = New B () End Sub End Class Patrón de delegado de clase Shared Sub Main () Dim c Como nuevo C () c . f () c . gramo () do . toB () do . f () c . g () Sistema . consola _ Tecla de lectura () End Sub Fin de espacio de nombres de fin de clase Ejemplo no trivial Código fuente en VB.NET Importaciones System.Collections.Generic Imports System.Linq Imports System.Text Namespace Employees ''' <summary> ''' Clase para almacenar datos de empleados. ''' </summary> Clase Empleado Privado m_name As String Privado m_department As String Public Sub New ( nombre de ByVal As String , departamento de ByVal As String ) Yo . m_name = nombrame . _ m_departamento = departamento End Sub ''' <resumen> ''' Nombre del empleado. ''' </summary> Public ReadOnly Property Name () As String Get Return Me . m_name Fin Obtener propiedad final ''' <resumen> ''' Departamento de trabajo. ''' </summary> Public ReadOnly Property Department () As String Get Return Me . m_department End Obtener End Property End Class ''' <summary> ''' Clase para almacenar una lista de empleados. ''' </summary> Class EmployeesList Empleados privados como nueva lista ( de empleados ) () ''' <summary> ''' Propiedad para obtener y escribir un empleado por índice. ''' </summary> ''' <param name="index">Índice de empleados.</param> ''' <returns>Employee.</returns> Elemento de propiedad pública predeterminado ( ByVal index As Integer ) As Employee Get Devolver empleados ( índice ) End Get Set ( ByVal value As Employee ) empleados ( index ) = value End Set End Property ''' <resumen> ''' Agregando un nuevo empleado. ''' </summary> ''' <param name="employee">Nuevo empleado.</param> Public Sub Add ( ByVal employee As Employee ) empleados . Añadir ( empleado ) End Sub ''' <resumen> ''' Eliminar un empleado existente. ''' </summary> ''' <param name="employee">Empleado a eliminar.</param> Public Sub Remove ( ByVal employee As Employee ) empleados . Eliminar ( empleado ) End Sub ''' <resumen> ''' Búsqueda secuencial de un empleado por nombre. ''' </summary> ''' <param name="name">Nombre del empleado.</param> ''' <returns>Índice de empleados.</returns> Función pública GetIndexOfEmployeeByName ( ByVal name As String ) As Integer Dim índice como entero = - 1 For i As Integer = 0 Para empleados . Recuento - 1 Si empleados ( i ). Nombre = nombre Entonces índice = i Salir Para Finalizar Si Siguiente Regresar índice Finalizar Función ''' <resumen> ''' Búsqueda secuencial de un empleado por nombre. ''' </summary> ''' <param name="name">Nombre del empleado.</param> ''' <param name="offset">Posición desde la que empezar a buscar.</param> '' ' < devuelve>Índice de empleados.</retornos> Función pública GetIndexOfEmployeeByName ( Nombre de ByVal As String , ByVal offset As Integer ) As Integer Dim index As Integer = - 1 For i As Integer = compensación Para empleados . Recuento - 1 Si empleados ( i ). Nombre = nombre Entonces índice = i Salir Para Finalizar si Siguiente Regresar índice Finalizar función Finalizar clase Class Program Shared Sub Main () 'Crear una lista de empleados y agregarle entradas Dim empList As New EmployeesList () empList . Agregar ( Nuevo empleado ( "Shlensky Dmitry" , "estudio web" )) empList . Agregar ( Nuevo empleado ( "Kusy Nazar" , "estudio web" )) empList . Agregar ( Nuevo empleado ( "Urraca Orest" , "estudio web" ))) 'Buscando al empleado Kusyi Nazar y mostrando el resultado al buscar desde el principio y desde la 2da posición Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" ). ToString ()) Consola . WriteLine ( empList . GetIndexOfEmployeeByName ( "Kusy Nazar" , 2 ). ToString ()) 'Buscar y eliminar empleado Soroka Orestes empList . Quitar ( empList ( empList . GetIndexOfEmployeeByName ( "Urraca Orestes" ))) Consola . Leer () Fin sub Fin de espacio de nombres de fin de clase

Véase también

Notas

  1. Bruce Eckel. Filosofía Java. - 4ª edición. - LLC Publishing House "Peter", 2016. - S. 215. - 1165 p.

Literatura

  • Julian Bucknell "Algoritmos fundamentales y estructuras de datos en Delphi". ed. Diasoft 2003
  • Grand M. Patrones de diseño en Java. 2004
  • Bruce Eckel "Filosofía de Java". ed. "Pedro" 2016