El principio de Inversion of control y Flex

Inversion of Control o IoC, es un principio de la ingeniería del software. Este patrón que se ha puesto de moda actualmente gracias a frameworks como Swiz. En este artículo veremos indagaremos un poco en todos estos conceptos usando Swiz como base para el estudio…

Se concibe como una manera de desacoplar las clases de las dependencias a otras, inyectando estas dependencias en lugar de tener referencias directas a implementaciones específicas. Una clase con referencias directas a otras clases, está acoplada, depende de estas clases. También es cierto que una clase que no tiene referencias a otras clases probablemente no será muy útil. Este patrón es una solución a estas dependencias. Este principio abstracto describe un aspecto de los patrones arquitecturales de la ingeniería del software, en el cual el flujo del control del sistema se invierte en comparación a la arquitectura tradicional.

En la programación imperativa las instrucciones se ejecutan según la lógica de la vida de un proceso. En el caso del IoC, el programador escribe la respuesta deseada a unos eventos concretos o respuestas de datos. Luego, las entidades externas adquieren el control en una determinada llamada y se encargarán de ejecutar el proceso. La esencia del IoC reside en el “Hollywood Principle“, que viene a decir lo siguiente: “No nos llame, ya le llamaremos nosotros”. Este principio permite crear código de alta cohesión y con un bajo acoplamiento.

IoC es un estilo de construcción de software reusable, donde el código controla la ejecución de un problema específico, con la connotación que el código reutilizable y el problema específico de código se desarrollan independientemente, y el resultado suele ser una única aplicación integrada.
Los siguientes conceptos son aplicaciones directas del principio de IoC:

    • Programación orientada a eventos

    • Inyección de dependencias: Es una forma específica del principio de Inversion of Control, que invierte el proceso de obtención de una dependencia que se requiere. Normalmente, si un objeto nececita tener acceso a un determinado servicio, el objeto tiene la responsabilidad de acceder al servicio. Usando la inyección de dependencias, cuando el servicio se implementa, éste es inyectado al objeto mediante un mecanismo externo.

Ejemplo de aplicación

Imaginemos una aplicación financiera con diferentes recursos externos, como conexiones a una base de datos. Tradicionalmente, el código para conectar a la base de datos se reduce a un procedimiento en algún lugar de la aplicación. Así es difícil cambiar la base de datos o testear el código sin una base de datos.
Hay diferentes patrones para reducir el acoplamiento, en el mundo java existe el Service Locator pattern, por ejemplo. Para solucionar este problema, Inversion of Control permite tener la configuración de la base de datos en un fichero externo al código. El patrón se encarga de resolver las dependencias y servirlas a los componentes que las precisen.

Swiz, el framework IoC

Uno de los conceptos fundamentales de Swiz son los Beans. Un Bean en Swiz es un fichero MXML que extiende de la clase BeanLoader de Swiz. En el tag BeanLoader,tenemos una serie de declaraciones posibles. A continuación tenemos un ejemplo:

El motor de introspección

Cuando se inicia el motor de introspección, mira todos los objetos que han sido registrados y el BeanFactory crea y mantiene instancias de los objectos para poder acceder a ellos.

IoC y el patrón de Dependency Injection aplicados a Flex

Entre los patrones más importantes en el desarrollo de RIA’s está el patrón de Dependency Injection. Este concepto originado por Martin Fowler es el que conocemos como Inversion of Control. Según el mismo Fowler, este patrón tiene como mayor objetivo la separación entre la configuración y la implementación.

Hay tres niveles básicos de inyección de dependencias:

Interface Injection: es el proceso por el cual todas las dependencias son inyectadas en un objeto mediante una interface. Un ejemplo en el código que sigue es la clase ConfigurationManager, que podría implementar una interface que definiera las operaciones que se necesitan inyectar en la implementación de ésta.

Setter Injection: Es el proceso de inyectar dependencias a través de setters públicos. Mediante este tipo de inyección, la clase ConfigurationManager podría proveer setters públicos con los cuales una clase Configuration inyectaría los datos necesarios.

Constructor Injection: Es el proceso de inyección de dependencias mediante argumentos en el constructor de una clase. Utilizando este tipo de inyección de dependencias, la clase Configuration concreta podría ser inyectada fácilmente.

La inyección mediante constructor o setters son las maneras preferidas por unanimidad entre los programadores. La inyección mediante interfaces tiene más problemas, ya que implica tener muchas interfaces que luego deberán ser implementadas.
 
Para ver los tipos de inyección de dependencias tenemos el siguiente código escrito en AS3, este código concibe un ejemplo típico de dependencia entre clases:

En el código anterior se ven claramente las dependencias: la clase ConfigurationManager tiene una dependencia hacia la clase XMLConfiguration. Es un tipo de dependencia normal, pero el primer problema es que la propiedad config es una implementación concreta. Esto viola uno de los principios de la Programación Orientada a Objetos, el de la ocultación de código, es decir programar contra interfaces, no contra implementaciones. Podemos razonar esto diciendo que sólo se cargará el valor de la propiedad config desde una única clase y por eso no es necesario crear ina interface.
De todas maneras, este código se puede mejorar simplemente refactorizando la clase ConfigurationManager, definiendo la propiedad config como una abstracción, la llamaremos IConfiguration.

Este cambio va en la dirección correcta del paradigma POO, de todas maneras aún podemos apreciar diferentes problemas en este código, por ejemplo la instanciación de la clase XMLConfiguration directamente en en constructor de la clase ConfigurationManager. Este es un punto claro donde aplicar la inyección de dependencias para proveer una solución a la recurrencia de controlar las dependencias entre clases y como se proporcionan estas dependencias. Cuando se implementa el patrón IoC en una aplicación, se debe crear un contexto que defina todas las dependencias.

Hay numerosos frameworks para distintas plataformas que que proporcionan implementaciones para los tres tipos de Inyección de Dependencias. Uno de los más conocidos es el Spring Framework para Java/J2EE. Para Flex, a parte de Swiz, se considera una muy buena alternativa el Prana Framework.

Comparte:



6votos  Vota!!

Acerca de esta entrada