Inversión de control - Inversion of control

En ingeniería de software , la inversión de control ( IoC ) es un principio de programación. IoC invierte el flujo de control en comparación con el flujo de control tradicional. En IoC, las partes de un programa informático escritas a medida reciben el flujo de control de un marco genérico . Una arquitectura de software con este diseño invierte el control en comparación con la programación procedimental tradicional : en la programación tradicional, el código personalizado que expresa el propósito del programa llama a bibliotecas reutilizables para encargarse de tareas genéricas, pero con la inversión de control, es el marco. que llama al código personalizado o específico de la tarea.

La inversión de control se utiliza para aumentar la modularidad del programa y hacerlo extensible , y tiene aplicaciones en programación orientada a objetos y otros paradigmas de programación . El término fue utilizado por Michael Mattsson en una tesis, tomada de allí por Stefano Mazzocchi y popularizada por él en 1999 en un proyecto desaparecido de la Apache Software Foundation, Avalon , luego popularizado en 2004 por Robert C. Martin y Martin Fowler .

El término está relacionado, pero es diferente, al principio de inversión de dependencia , que se ocupa de desacoplar las dependencias entre las capas de alto y bajo nivel a través de abstracciones compartidas . El concepto general también está relacionado con la programación impulsada por eventos en el sentido de que a menudo se implementa utilizando IoC de modo que el código personalizado comúnmente solo se ocupa del manejo de eventos, mientras que el bucle de eventos y el envío de eventos / mensajes lo maneja el marco o el entorno de ejecución.

Visión general

Por ejemplo, con la programación tradicional, la función principal de una aplicación puede realizar llamadas a funciones en una biblioteca de menús para mostrar una lista de comandos disponibles y pedirle al usuario que seleccione uno. Por lo tanto, la biblioteca devolvería la opción elegida como el valor de la llamada a la función, y la función principal usa este valor para ejecutar el comando asociado. Este estilo era común en las interfaces basadas en texto . Por ejemplo, un cliente de correo electrónico puede mostrar una pantalla con comandos para cargar correo nuevo, responder el correo actual, crear correo nuevo, etc., y la ejecución del programa se bloquearía hasta que el usuario presione una tecla para seleccionar un comando.

Con la inversión de control, por otro lado, el programa se escribiría utilizando un marco de software que conozca los elementos gráficos y de comportamiento comunes, como sistemas de ventanas , menús, control del mouse, etc. El código personalizado "llena los espacios en blanco" para el marco, como proporcionar una tabla de elementos del menú y registrar una subrutina de código para cada elemento, pero es el marco que monitorea las acciones del usuario e invoca la subrutina cuando se selecciona un elemento del menú. . En el ejemplo del cliente de correo, el marco podría seguir las entradas del teclado y del mouse y llamar al comando invocado por el usuario por cualquiera de los medios, y al mismo tiempo monitorear la interfaz de red para averiguar si llegan nuevos mensajes y actualizar la pantalla cuando algunos se detecta actividad de red. El mismo marco podría usarse como esqueleto para un programa de hoja de cálculo o un editor de texto. Por el contrario, el marco no sabe nada sobre navegadores web, hojas de cálculo o editores de texto; implementar su funcionalidad requiere código personalizado.

La inversión de control conlleva la fuerte connotación de que el código reutilizable y el código específico del problema se desarrollan de forma independiente aunque operen juntos en una aplicación. Las devoluciones de llamada , los programadores , los bucles de eventos , la inyección de dependencias y el método de plantilla son ejemplos de patrones de diseño que siguen el principio de inversión del control, aunque el término se usa más comúnmente en el contexto de la programación orientada a objetos .

La inversión de control tiene los siguientes propósitos de diseño:

  • Para desacoplar la ejecución de una tarea de implementación.
  • Centrar un módulo en la tarea para la que está diseñado.
  • Liberar módulos de suposiciones sobre cómo otros sistemas hacen lo que hacen y, en cambio, se basan en contratos .
  • Para prevenir efectos secundarios al reemplazar un módulo.

A la inversión del control a veces se le llama en broma el "Principio de Hollywood: no nos llame, nosotros le llamaremos".

Fondo

La inversión de control no es un término nuevo en la informática. Martin Fowler remonta la etimología de la frase a 1988, pero está estrechamente relacionada con el concepto de inversión de programa descrito por Michael Jackson en su metodología de programación estructurada de Jackson en la década de 1970. Un analizador de abajo hacia arriba puede verse como una inversión de un analizador de arriba hacia abajo : en un caso, el control está en el analizador, mientras que en el otro caso, está en la aplicación receptora.

La inyección de dependencia es un tipo específico de IoC. Un localizador de servicios como Java Naming and Directory Interface (JNDI) es similar. En un artículo de Loek Bergman, se presenta como un principio arquitectónico.

En un artículo de Robert C. Martin , el principio de inversión de dependencia y la abstracción por capas se unen. Su razón para utilizar el término "inversión" es en comparación con los métodos tradicionales de desarrollo de software. Describe el desacoplamiento de servicios mediante la abstracción de capas cuando habla de inversión de dependencia. El principio se utiliza para averiguar dónde están los límites del sistema en el diseño de las capas de abstracción.

Descripción

En la programación tradicional, el flujo de la lógica empresarial está determinado por objetos que están vinculados estáticamente entre sí. Con la inversión de control, el flujo depende del gráfico de objetos que se construye durante la ejecución del programa. Este flujo dinámico es posible gracias a las interacciones de objetos que se definen mediante abstracciones. Este enlace en tiempo de ejecución se logra mediante mecanismos como la inyección de dependencias o un localizador de servicios . En IoC, el código también podría estar vinculado estáticamente durante la compilación, pero encontrando el código para ejecutar leyendo su descripción de la configuración externa en lugar de con una referencia directa en el código mismo.

En la inyección de dependencia, un objeto o módulo dependiente se acopla al objeto que necesita en tiempo de ejecución . Qué objeto en particular satisfará la dependencia durante la ejecución del programa normalmente no se puede conocer en tiempo de compilación mediante el análisis estático . Aunque aquí se describe en términos de interacción de objetos, el principio puede aplicarse a otras metodologías de programación además de la programación orientada a objetos .

Para que el programa en ejecución vincule objetos entre sí, los objetos deben poseer interfaces compatibles . Por ejemplo, la clase Apuede delegar el comportamiento a la interfaz Ique es implementada por la clase B; el programa instancia Ay B, y luego inyecta Ben A.

Técnicas de implementación

En la programación orientada a objetos , existen varias técnicas básicas para implementar la inversión de control. Estos son:

En un artículo original de Martin Fowler, se discuten las tres primeras técnicas diferentes. En una descripción sobre inversión de tipos de control, se menciona el último. A menudo, la búsqueda contextualizada se realizará mediante un localizador de servicios.

Ejemplos de

La mayoría de los marcos como .NET o Enterprise Java muestran este patrón:

public class ServerFacade {
    public <K, V> V respondToRequest(K request) {
        if (businessLayer.validateRequest(request)) {
            Data data = DAO.getData(request);
            return Aspect.convertData(data);
        }
        return null;
    }
}

Este esquema básico en Java ofrece un ejemplo de código que sigue la metodología de IoC. Sin embargo, es importante que en la ServerFacademayoría de los casos se hagan suposiciones sobre los datos devueltos por el objeto de acceso a datos (DAO).

Aunque todas estas suposiciones pueden ser válidas en algún momento, acoplan la implementación del ServerFacadea la implementación de DAO. Diseñar la aplicación en forma de inversión de control entregaría el control completamente al objeto DAO. El código se convertiría entonces en

public class ServerFacade {
    public <K, V> V respondToRequest(K request, DAO dao) {
        return dao.getData(request);
    }
}

El ejemplo muestra que la forma en que respondToRequestse construye el método determina si se utiliza IoC. Es la forma en que se utilizan los parámetros lo que define IoC. Esto se parece al estilo de paso de mensajes que utilizan algunos lenguajes de programación orientados a objetos.

Ver también

Referencias

  1. ^ Johnson, Ralph E .; Foote, Brian (junio-julio de 1988). "Diseño de clases reutilizables" . Revista de programación orientada a objetos . 1 (2): 22–35. CiteSeerX  10.1.1.101.8594 . Consultado el 29 de abril de 2014 .
  2. ^ Mattsson, Michael (febrero de 1996). "Marcos orientados a objetos, un estudio de cuestiones metodológicas" . Departamento de Ciencias de la Computación, Universidad de Lund. CiteSeerX  10.1.1.36.1424 . LU-CS-TR: 96-167.
  3. ^ Stefano Mazzocchi (22 de enero de 2004). "Sobre la inversión de control" . Archivado desde el original el 2 de febrero de 2004.
  4. ^ a b Inyección de dependencia .
  5. ^ Inversión de control en Bliki de Martin Fowler
  6. ^ "Introducción al método de diseño de Jackson" (PDF) .
  7. ^ Índice de archivo en Wayback Machine Inside Architecture: escribir una vez, ejecutar en cualquier lugar por Loek Bergman
  8. ^ El principio de inversión de dependencia de Robert C. Martin
  9. ^ Inversión de contenedores de control y el patrón de inyección de dependencia por Martin Fowler
  10. ^ Tipos de IoC Archivado el 15 de junio de 2009 en Wayback Machine.

enlaces externos