Ejemplo de preocupación transversal

121

¿Cuál es un buen ejemplo de a cross-cutting concern? El ejemplo de registro médico en la página de wikipedia me parece incompleto.

Específicamente a partir de este ejemplo, ¿por qué el registro conduciría a la duplicación de código ( dispersión )? (Además de llamadas simples como en log("....")todas partes, que no parece gran cosa).

¿Cuál es la diferencia entre ay core concerna cross-cutting concern?

Mi objetivo final es comprender mejor el AOP.

jlars62
fuente

Respuestas:

235

Antes de comprender la preocupación transversal , tenemos que comprender la preocupación .

Una preocupación es un término que se refiere a una parte del sistema dividida en función de la funcionalidad.

Las preocupaciones son de dos tipos:

  1. Las preocupaciones que representan una funcionalidad única y específica para los requisitos primarios se conocen como preocupaciones centrales .
    O
    La funcionalidad principal del sistema se conoce como preocupaciones centrales.
    Por ejemplo : lógica empresarial
  2. Las preocupaciones que representan funcionalidades para requisitos secundarios se conocen como preocupaciones transversales o preocupaciones de todo el sistema .
    O
    La preocupación transversal es una preocupación que se aplica a toda la aplicación y afecta a toda la aplicación.
    Por ejemplo: el registro, la seguridad y la transferencia de datos son preocupaciones que se necesitan en casi todos los módulos de una aplicación, por lo tanto, son preocupaciones transversales.

Cortesía

ingrese la descripción de la imagen aquí

Esta figura representa una aplicación típica que se divide en módulos. La principal preocupación de cada módulo es proporcionar servicios para su dominio particular. Sin embargo, cada uno de estos módulos también requiere funcionalidades auxiliares similares, como el registro de seguridad y la gestión de transacciones. Un ejemplo de preocupaciones transversales es el "registro", que se utiliza con frecuencia en aplicaciones distribuidas para ayudar a la depuración mediante el seguimiento de llamadas a métodos. Supongamos que registramos tanto al principio como al final de cada cuerpo de función. Esto resultará en un corte transversal de todas las clases que tienen al menos una función.

(Cortesía)

Premraj
fuente
1
"La preocupación transversal es una preocupación que se aplica en toda la aplicación" ➤ No estoy seguro de esto, ya que la gestión de transacciones no es aplicable 'en toda' la aplicación, pero sigue siendo una preocupación transversal. Y la imagen no me dice nada para ser honesto, solo es confuso ..
Koray Tugay
Buena explicación, pero tengo un pequeño problema con la imagen en la que llamamos a estas preocupaciones, preocupaciones transversales, no transversales, y creo que sería mejor cortar otras preocupaciones con preocupaciones transversales, y no de otra manera. Desarrollo orientado a aspectos
similares
aún así, la respuesta no explica el problema con simplemente usar algo como Log4j y registrar como LogManager.getLogger (). info (ModuleName, msg)
Vicky Singh
49

Creo que el mejor ejemplo de una preocupación transversal es el comportamiento transaccional. Tener que poner bloques try-catch con llamadas de confirmación y reversión en todos sus métodos de servicio sería repelente, por ejemplo. Anotar los métodos con un marcador que AOP puede usar para encapsularlos con el comportamiento transaccional deseado es una gran ganancia.

Otro buen candidato como ejemplo de preocupación transversal es la autorización. Anotar un método de servicio con un marcador que indica quién puede llamarlo y dejar que algunos consejos de AOP decidan si permitir la llamada al método o no, puede ser preferible a manejar eso en el código del método de servicio.

Implementar el registro con el asesoramiento de AOP podría ser una forma de obtener más flexibilidad, de modo que pueda cambiar lo que se registra cambiando un punto de unión. En la práctica, no veo proyectos que hagan eso con mucha frecuencia. Normalmente, el uso de una biblioteca como log4j que le permite filtrar por nivel de registro y categoría, en tiempo de ejecución si es necesario, funciona bastante bien.

Una preocupación fundamental es la razón por la que existe la aplicación, la lógica empresarial que la aplicación automatiza. Si tiene una aplicación de logística que maneja el envío de carga, averiguar cuánta carga puede empacar en un camión o cuál es la mejor ruta que puede tomar el camión para dejar sus entregas pueden ser preocupaciones fundamentales. Las preocupaciones transversales suelen ser detalles de implementación que deben mantenerse separados de la lógica empresarial.

Nathan Hughes
fuente
2
Entonces, aunque el comportamiento transaccional realmente solo existe en la capa de acceso a datos, debido a que los bloques try-catch están duplicados en muchos de los métodos, se considera transversal. Mi percepción original era que la transversalidad significaba que el código abarcaba múltiples capas de la aplicación.
jlars62
4
@ jlars62: corte transversal significa que va en ángulo recto con las características.
Nathan Hughes
7
@ jlars62: por en ángulo recto quiero decir: piensa en una característica como una pila de capas. una preocupación transversal puede aplicarse a una sola capa, pero es común a todas las entidades.
Nathan Hughes
La autorización de @NathanHughes es un buen ejemplo. Acabo de refactorizar mi aplicación para poner todo el código de autorización en una arquitectura transversal y funcionó de maravilla para limpiar una gran cantidad de código. Considero el dominio como una casa. Si tiene la llave para entrar, puede hacer lo que quiera allí (se presume que es un propietario). Pero no cerraría todas las puertas de la casa y exigiría una entrada con llave. O estás dentro o no estás.
Richard
El "comportamiento transaccional" puede ser común a muchas funciones, pero esto no será "transversal" porque no "cruza" las capas. La razón, por ejemplo, la tala es una preocupación transversal se debe a que es posible que quiera entrar en la capa de presentación, capa de negocio, etc. capa de datos
CodingYoshi
14

Además de la respuesta aceptada, quiero mencionar otro ejemplo de una preocupación transversal: la comunicación remota. Digamos que solo quiero llamar a otros componentes en mi ecosistema localmente como si estuvieran ejecutándose en proceso. Quizás en algunos casos incluso lo hagan. Pero ahora quiero ejecutar mis servicios distribuidos en una nube o clúster. ¿Por qué debería preocuparme por este aspecto como desarrollador de aplicaciones? Un aspecto podría encargarse de averiguar a quién llamar y cómo, serializando los datos transmitidos si es necesario y realizando una llamada remota. Si todo se estaba ejecutando en proceso, el aspecto simplemente reenviaría la llamada local. En el lado del destinatario de la llamada, el aspecto deserializaría los datos, realizaría la llamada local y devolvería el resultado.

Ahora permítanme contarles una pequeña historia sobre cosas "triviales" como la salida de registros: Hace apenas unas semanas, refactoricé una base de código compleja, pero no demasiado grande (alrededor de 250K líneas de código) para un cliente. En unos pocos cientos de clases se utilizó un tipo de marco de registro, en otros pocos cientos se utilizó otro. Luego hubo varios miles de líneas deSystem.out.println(*)donde realmente debería haber una salida de registro. Así que terminé arreglando miles de líneas de código esparcidas por la base del código. Afortunadamente, podría usar algunos trucos inteligentes en IntelliJ IDEA (búsqueda y reemplazo estructural) para acelerar toda la acción, pero ¿no crees que fue trivial? Claro, el registro de depuración fuertemente dependiente del contexto siempre ocurrirá dentro del cuerpo de un método, pero muchos tipos importantes de registro, como el rastreo de llamadas al método (incluso jerárquicamente con una salida bien sangrada), el registro de excepciones manejadas o no controladas, la auditoría de usuarios (registro de llamadas a métodos restringidos basados ​​en roles de usuario) y así sucesivamente se pueden implementar fácilmente en aspectos sin que contaminen el código fuente. El desarrollador de aplicaciones cotidiano no necesita pensar en ello o incluso ver las llamadas del registrador esparcidas por la base del código.

Puedo encontrar explicaciones similares para otras preocupaciones transversales. Mantener el código limpio y libre de dispersiones y enredos IMO es una cuestión de profesionalismo, no algo opcional. Por último, pero no menos importante, mantiene el código legible, mantenible y refactorizable. Amén.

kriegaex
fuente
0

Las preocupaciones transversales son los escenarios que siempre deben estar presentes independientemente del tipo de aplicación.

Por ejemplo, registro, seguridad, perfiles de rendimiento, localización, accesibilidad, transacciones, etc. Independientemente del software que estamos construyendo, se necesita registro (de lo contrario, cómo alguien depurará u obtendrá información relevante de los datos de producción). Se necesita seguridad (autenticación / autorización, etc.) cuando solo un usuario auténtico puede ingresar a la aplicación con el conjunto correcto de privilegios. Necesitamos saber cómo se desempeña su aplicación, luego necesitamos hacer perfiles. En caso de que la aplicación sea utilizada por usuarios internacionales (con su propio idioma localizado), entonces debemos admitir la misma en la aplicación. La accesibilidad son casos de usabilidad para que las personas con discapacidad usen nuestra aplicación.

Ahora, independientemente de si nuestra aplicación está basada en el escritorio, en la web, etc., si necesita ser utilizada por los usuarios finales en toda la geografía en el entorno de producción, se necesitan cortes transversales. Hasta ahora no he dicho nada acerca de qué se trata la aplicación, etc., pero dada la lista de preocupaciones que deben abordarse antes de lanzarla a los usuarios finales en el entorno de producción. y eso es todo sobre preocupaciones transversales (que deben ser manejadas por todas las aplicaciones / métodos / clases, es decir, en varios niveles).

bharatj
fuente