Está en la página 1de 6

3.

- COMPONENTES DE LA CAPA DE APLICACIÓN


La Capa de Aplicación puede incluir diferentes tipos de componentes, pero
ciertamente, el tipo de componente principal será el de SERVICIO de Aplicación,
como explicamos a continuación.
3.1.- Servicios de Aplicación
El SERVICIO de Aplicación es otro tipo más de Servicio, cumpliendo con las
directrices de su patrón (SERVICE pattern). Básicamente deben ser objetos sin
estados que coordinen ciertas operaciones, en este caso operaciones y tareas
relativas a la Capa de Aplicación (Tareas requeridas por el software/aplicación, no
por la lógica del Dominio).
Otra función de los Servicios de Aplicación es encapsular y aislar a la capa de
infraestructura de persistencia de datos. Así pues, en la capa de aplicación
realizaremos la coordinación de transacciones y persistencia de datos (solo la
coordinación o llamada a los Repositorios), validaciones de datos y aspectos de
seguridad como requerimientos de autenticación y autorización para ejecutar
componentes concretos, etc.
También los SERVICIOS deben ser normalmente el único punto o tipo de
componente de la arquitectura por el que se acceda a las clases de infraestructura
de persistencia de datos (Repositorios) desde capas superiores. No debería, por
ejemplo, poder invocar directamente desde la Capa de Presentación (p.e. Web)
objetos Repositorios de la Capa de Persistencia y Acceso a Datos.
Como se puede observar en el diagrama, la interacción entre los diferentes
objetos de las capas de la aplicación normalmente comenzará en un Servicio de
Aplicación, el cual servirá de concentrador o hub de los diferentes tipos de
acciones de la aplicación.
El aspecto fundamental de esta capa es no mezclar requerimientos de Software
(coordinación de la persistencia, conversiones a diferentes formatos de datos,
optimizaciones, Calidad de Servicio, etc.) con la Capa de Dominio que solo debe
contener pura lógica de Negocio. En el diagrama UML de secuencia que
mostramos a continuación, se pueden observar los objetos de la Capa de
Aplicación (el Servicio que origina la transferencia bancaria en la aplicación), los
objetos del Dominio y como posteriormente desde el Servicio de aplicación se
llama a los objetos Repositorio y UoW.

En esta interacción entre objetos, solamente las llamadas a métodos


ChargeMoney() y CreditMoney() son puramente de negocio/Dominio. El resto de
las interacciones son aspectos necesarios de la aplicación (consulta de datos de
cada cuenta y persistencia de datos mediante Repositorios; uso de UoW etc.), y
por lo tanto, acciones a coordinar desde la Capa de Aplicación.
RESUMEN SERVICIOS DE APLICACIÓN
El SERVICE pattern o patrón de servicio es un patrón de diseño de software que
se utiliza para separar la lógica de negocio de la lógica de aplicación. En este
patrón, los servicios son objetos que proporcionan una funcionalidad específica a
otras partes del sistema.
En el contexto de la capa de aplicación, el servicio de aplicación es otro tipo de
servicio que cumple con las directrices del patrón de servicio. Los servicios de
aplicación son objetos que coordinan ciertas operaciones y tareas relativas a la
capa de aplicación, es decir, aquellas tareas que son requeridas por el software o
la aplicación, no por la lógica del dominio.
Un servicio de aplicación es un objeto sin estado, lo que significa que no mantiene
ningún estado interno entre llamadas a los métodos. Los servicios de aplicación
suelen ser utilizados para implementar la lógica de la interfaz de usuario, la
gestión de sesiones, la autenticación y autorización, y otros aspectos de la capa
de aplicación.
En resumen, el servicio de aplicación es un tipo de servicio que cumple con las
directrices del patrón de servicio y se utiliza para coordinar operaciones y tareas
relativas a la capa de aplicación. Estos servicios son objetos sin estado que se
utilizan para implementar la lógica de la interfaz de usuario y otros aspectos de la
capa de aplicación.
3.2.- Desacoplamiento entre SERVICIOS de APLICACION y REPOSITORIOS
Al desacoplar todos los objetos con dependencias mediante IoC y DI, también
quedará desacoplada la capa de lógica de aplicación con respecto a las capas
inferiores como los Repositorios (Pertenecientes a la Capa de Infraestructura de
Persistencia de Datos). De esta forma podemos configurar dinámicamente o en
tiempo de compilación y testing, si se quiere realmente acceder a los repositorios
reales de datos (Bases de datos, etc.), a un segundo sistema de
repositorios/almacén diferente o incluso si se quiere acceder a „falsos repositorios‟
(repositorios stub o fake repositories) de forma que si lo único que queremos hacer
es ejecutar un gran volumen de pruebas unitarias siempre justo después de
realizar cambios en la lógica de negocio y compilar, esto se realizará de una forma
rápida y ágil (sin ralentizar el desarrollo) porque no estaremos accediendo a bases
de datos al realizar dichas pruebas unitarias (solo a repositorios de tipo „mock‟ o
„stub‟) para realizar dicho gran volumen de pruebas unitarias. Adicionalmente
deberemos poder realizar „pruebas de integración‟ donde ahí si se realizarán las
pruebas contra la Base de Datos real a la que acceden los Repositorios.
Normalmente un método de una clase SERVICIO de Aplicación, invocará a otros
objetos (del dominio o de persistencia de datos), formando reglas o transacciones
completas (como en el ejemplo un método que implemente una Transferencia
Bancaria, llamado BankingManagementService::PerformTransfer(), que realizaría
una llamada al Dominio para que se realicen las operaciones de negocio relativas
a la transferencia (internamente en el Dominio, ::Credit() y ::Debit()), y
posteriormente llamando a los métodos de persistencia de Repositorios para que
la transferencia quede grabada/reflejada en el almacén persistente (una base de
datos, probablemente). Todas esas llamadas entre diferentes objetos de las
diferentes capas (especialmente en lo relativo a infraestructura) deberán ser
llamadas desacopladas mediante interfaces e inyección de dependencias. El único
caso que no tiene mucho sentido desacoplar mediante DI son las entidades del
Dominio, pues en las entidades del Dominio no es normal querer sustituirlas por
otra versión que cumpla el mismo interfaz.
RESUMEN DESACOPLAMIENTO ENTRE SERVICIOS DE APLICACION Y
REPOSITORIOS
El desacoplamiento entre servicios de aplicación y repositorios se refiere a la
separación de la lógica de negocio de la lógica de acceso a datos. En un sistema
bien diseñado, los servicios de aplicación y los repositorios son componentes
independientes que no dependen directamente el uno del otro.
Los servicios de aplicación se encargan de coordinar las operaciones y tareas de
la capa de aplicación, mientras que los repositorios se encargan de interactuar con
el almacenamiento de datos. En lugar de interactuar directamente con los
repositorios, los servicios de aplicación utilizan interfaces abstractas para
comunicarse con ellos.
Este enfoque de diseño presenta varias ventajas. En primer lugar, el
desacoplamiento entre los servicios de aplicación y los repositorios facilita el
mantenimiento y la evolución del sistema. Si se cambia la implementación de un
repositorio, por ejemplo, se puede hacer sin afectar los servicios de aplicación que
lo utilizan.
En segundo lugar, el desacoplamiento entre los servicios de aplicación y los
repositorios permite una mayor flexibilidad en la elección de las tecnologías y
herramientas utilizadas en cada uno de ellos. Esto permite seleccionar la
tecnología más adecuada para cada componente, en lugar de estar limitado a una
sola tecnología para todo el sistema.
Por último, el desacoplamiento entre los servicios de aplicación y los repositorios
mejora la modularidad del sistema, lo que facilita la comprensión y el
mantenimiento del código. Cada componente puede ser diseñado y desarrollado
de forma independiente, lo que simplifica su comprensión y reduce la complejidad
general del sistema.
En resumen, el desacoplamiento entre servicios de aplicación y repositorios es un
enfoque de diseño que separa la lógica de negocio de la lógica de acceso a datos.
Esto facilita el mantenimiento y la evolución del sistema, permite una mayor
flexibilidad en la elección de tecnologías y mejora la modularidad del código.
3.2.1.- Patrón “Unidad de Trabajo” (UNIT OF WORK)
El concepto del patrón de UNIT OF WORK (UoW) está muy ligado al uso de
REPOSITORIOS. En definitiva, un Repositorio no accede directamente a los
almacenes (comúnmente bases de datos) de una forma directa cuando le decimos
que realice una actualización (update/insert/delete). Por el contrario, lo que realiza
es un registro en memoria de las operaciones que „quiere‟ realizar. Y para que
realmente se realicen sobre el almacén o base de datos, es necesario que un ente
de mayor nivel aplique dichos cambios a realizar contra el almacén. Dicho ente o
concepto de nivel superior es el UNIT OF WORK.
El patrón de UNIT OF WORK encaja perfectamente con las transacciones, pues
podemos hacer coincidir un UNIT OF WORK con una transacción, de forma que
justo antes del „commit‟ de una transacción aplicaríamos con el UoW las
diferentes operaciones, agrupadas todas de una vez, con lo que el rendimiento se
optimiza y Capa de Aplicación 221 especialmente se minimizan los bloqueos en
base de datos. Por el contrario, si hiciéramos uso solamente de clases de acceso
a datos (tradicionales DAL) dentro de una transacción, la transacción tendría una
mayor duración y nuestros objetos estarían aplicando operaciones de la
transacción mezcladas en el tiempo con lógica del dominio, por lo que el tiempo
puramente para la transacción será siempre mayor con el consiguiente aumento
de tiempo en bloqueos.
El patrón UNIT OF WORK fué definido por Martin Fowler (Fowler, Patterns of
Enterprise Application Architecture, 184). De acuerdo con Martin, “Un UNIT OF
WORK mantiene una lista de objetos afectados por una transacción de negocio y
coordina la actualización de cambios y la resolución de problemas de
concurrencia”.
El diseño del funcionamiento de un UNIT OF WORK puede realizarse de
diferentes formas, pero probablemente el más acertado (como adelantábamos
antes) consiste en que los Repositorios deleguen al UNIT OF WORK (UoW) el
trabajo de acceder al almacén de datos. Es decir, el UoW será el que realice
efectivamente las llamadas al almacén (en bases de datos, comunicar al servidor
de base de datos que ejecute sentencias SQL). El mayor beneficio de esta
aproximación es que los mensajes que manda el UoW son transparentes al
consumidor de los repositorios, puesto que los repositorios solamente le dicen al
UoW operaciones que deberá hacer cuando decida aplicar la unidad de trabajo.
RESUMEN PATRÓN “UNIDAD DE TRABAJO” (UNIT OF WORK)
El patrón de UNIT OF WORK (UoW) se utiliza en conjunto con REPOSITORIOS y
consiste en registrar en memoria las operaciones que se quieren realizar en un
almacén de datos, en lugar de hacer cambios directamente. Para aplicar los
cambios al almacén, se requiere de un ente de mayor nivel, que es el propio UoW.
El patrón de UoW se utiliza en transacciones y permite agrupar todas las
operaciones antes de aplicarlas, lo que optimiza el rendimiento y minimiza los
bloqueos en la base de datos. El diseño de UoW puede variar, pero lo más
acertado es que los Repositorios deleguen al UoW el trabajo de acceder al
almacén de datos y realizar las llamadas necesarias. Esto permite que los
mensajes enviados por el UoW sean transparentes para el consumidor de los
repositorios.
Servicios Workflows de Capa de Aplicación (Opcional)
Realmente esta sub-capa se trata de un caso especial de SERVICIOS de Aplicación que viene a dar
solución a algunas casuísticas determinadas dentro de distintas soluciones de software. Los
procesos de larga duración o bien los procesos en los que hay interacción, tanto humana como de
otros sistemas software, son un ejemplo claro de uso de flujos de trabajo. Modelar un proceso de
interacción humana, por ejemplo, directamente en el lenguaje de codificación seleccionado suele
oscurecer demasiado el verdadero propósito del mismo, impidiendo en muchos casos una posible
comprensión del mismo y por lo tanto disminuyendo la legibilidad. Al contrario, una capa de flujo
de trabajos nos permite modelar las distintas interacciones por medio de actividades y un
diseñador de control que de forma visual no da una idea clara del propósito del proceso a realizar.

Cuando se habla de flujos de trabajo, se habla generalmente de los pasos de estos flujos de
trabajo, a los que generalmente se les conoce como actividades. Cuando se hace una
implementación de esta subcapa es importante rentabilizar al máximo la reutilización de las
mismas y prestar atención a como se implementan, como puntos importantes cabrían destacar los
siguientes.

- Si las actividades hacen uso de mecanismos de persistencia deberían utilizar siempre que sea
posible los repositorios ya definidos.

- Las actividades pueden orquestar diferentes métodos de la subcapa de aplicación y servicios del
dominio.

La mayoría de los motores de flujo de trabajos existentes hoy en dia disponen de mecanismos
para garantizar la durabilidad de los mismos ante procesos de larga duración y/o caidas de
sistema. De forma usual estos sistemas se basan en bases de datos relaciones y por lo tanto
dispondrán de distintas operacionesn que podrían ser susceptibles de incorporar dentro de esta
sub capa, algunos ejemplos de operaciones podrían ser las siguientes.

- Rehidratación de los flujos de trabajo desde el sistema de persistencia a la memoria.

- Descarga de los flujos de trabajo desde la memoria hasta el sistema de persistencia.

- Comprobación de la existencia de un determinado flujo de trabajo en el sistema de persistencia.

- Almacenamiento de las correlaciones de las instancias de los flujos de trabajo en el sistema de


persistencia.

RESUMEN

En resumen, la subcapa de flujos de trabajo es una solución para procesos de


larga duración o procesos con interacciones humanas o de sistemas. Esta capa
permite modelar las interacciones mediante actividades y un diseñador de control,
lo que facilita la comprensión del proceso. Es importante rentabilizar al máximo la
reutilización de las actividades y prestar atención a cómo se implementan. Los
motores de flujo de trabajo tienen mecanismos para garantizar la durabilidad y
pueden basarse en bases de datos relacionales para incorporar operaciones como
la rehidratación, descarga, comprobación y almacenamiento de los flujos de
trabajo en el sistema de persistencia.

También podría gustarte