¿Qué es este idioma "Ejecutar alrededor" (o similar) del que he estado escuchando? ¿Por qué podría usarlo y por qué no querría usarlo?
java
language-agnostic
design-patterns
idioms
Tom Hawtin - tackline
fuente
fuente
Respuestas:
Básicamente es el patrón en el que escribe un método para hacer cosas que siempre se requieren, por ejemplo, asignación de recursos y limpieza, y hacer que la persona que llama pase "lo que queremos hacer con el recurso". Por ejemplo:
El código de llamada no tiene que preocuparse por el lado de apertura / limpieza: será atendido por él
executeWithFile
.Esto fue francamente doloroso en Java porque los cierres eran muy profundos, comenzando con Java 8, las expresiones lambda se pueden implementar como en muchos otros lenguajes (por ejemplo, expresiones lambda C # o Groovy), y este caso especial se maneja desde Java 7 con
try-with-resources
yAutoClosable
streams.Aunque "asignar y limpiar" es el ejemplo típico dado, hay muchos otros ejemplos posibles: manejo de transacciones, registro, ejecución de algún código con más privilegios, etc. Es básicamente un poco como el patrón de método de plantilla pero sin herencia.
fuente
La expresión Ejecutar alrededor se usa cuando tienes que hacer algo como esto:
Para evitar repetir todo este código redundante que siempre se ejecuta "alrededor" de sus tareas reales, debe crear una clase que se encargue automáticamente:
Este modismo mueve todo el código redundante complicado en un solo lugar y deja su programa principal mucho más legible (¡y mantenible!)
Eche un vistazo a esta publicación para ver un ejemplo de C #, y este artículo para un ejemplo de C ++.
fuente
Un Método Ejecutar Alrededor es donde pasa código arbitrario a un método, que puede realizar el código de configuración y / o desmontaje y ejecutar su código en el medio.
Java no es el lenguaje en el que elegiría hacer esto. Es más elegante pasar un cierre (o expresión lambda) como argumento. Aunque los objetos son posiblemente equivalentes a los cierres .
Me parece que el Método Ejecutar Alrededor es algo así como la Inversión de Control (Inyección de Dependencia) que puede variar ad hoc, cada vez que llama al método.
Pero también podría interpretarse como un ejemplo de Acoplamiento de control (decirle a un método qué hacer por su argumento, literalmente en este caso).
fuente
Veo que tiene una etiqueta Java aquí, así que usaré Java como ejemplo, aunque el patrón no sea específico de la plataforma.
La idea es que a veces tiene un código que siempre involucra la misma plantilla antes de ejecutar el código y después de ejecutarlo. Un buen ejemplo es JDBC. Siempre toma una conexión y crea una declaración (o declaración preparada) antes de ejecutar la consulta real y procesar el conjunto de resultados, y luego siempre realiza la misma limpieza repetitiva al final, cerrando la declaración y la conexión.
La idea con execute-around es que es mejor si puede factorizar el código repetitivo. Eso te ahorra algo de tipeo, pero la razón es más profunda. Aquí es el principio de no repetirse (DRY): aísla el código en una ubicación, por lo que si hay un error o necesita cambiarlo, o simplemente quiere entenderlo, todo está en un solo lugar.
Sin embargo, lo que es un poco complicado con este tipo de factorización es que tienes referencias que las partes "antes" y "después" deben ver. En el ejemplo de JDBC, esto incluiría la conexión y la declaración (preparada). Entonces, para manejar eso, esencialmente "envuelve" su código de destino con el código repetitivo.
Puede estar familiarizado con algunos casos comunes en Java. Uno es los filtros de servlet. Otro es AOP en torno a los consejos. Un tercero son las diversas clases xxxTemplate en Spring. En cada caso, tiene algún objeto contenedor en el que se inyecta su código "interesante" (por ejemplo, la consulta JDBC y el procesamiento del conjunto de resultados). El objeto contenedor hace la parte "antes", invoca el código interesante y luego hace la parte "después".
fuente
Consulte también Code Sandwiches , que analiza esta construcción en muchos lenguajes de programación y ofrece algunas ideas de investigación interesantes. Con respecto a la pregunta específica de por qué uno podría usarlo, el documento anterior ofrece algunos ejemplos concretos:
Y después:
El documento no explora por qué no usar este idioma, pero describe por qué es fácil equivocarse sin la ayuda a nivel de idioma:
fuente
Trataré de explicar, como lo haría con un niño de cuatro años:
Ejemplo 1
Papá Noel viene a la ciudad. Sus elfos codifican lo que quieran a sus espaldas y, a menos que cambien, las cosas se vuelven un poco repetitivas:
O esto:
.... ad nauseam un millón de veces con un millón de regalos diferentes: observe que lo único diferente es el paso 2. Si el paso dos es lo único que es diferente, entonces ¿por qué Santa está duplicando el código, es decir, por qué está duplicando los pasos? 1 y 3 un millón de veces? Un millón de regalos significa que está repitiendo innecesariamente los pasos 1 y 3 un millón de veces.
Ejecutar alrededor ayuda a resolver ese problema. y ayuda a eliminar el código. Los pasos 1 y 3 son básicamente constantes, permitiendo que el paso 2 sea la única parte que cambia.
Ejemplo # 2
Si aún no lo obtiene, aquí hay otro ejemplo: piense en un bocadillo: el pan en el exterior siempre es el mismo, pero lo que está en el interior cambia según el tipo de arena que elija (por ejemplo, jamón, queso, mermelada, mantequilla de maní, etc.). El pan siempre está en el exterior y no necesita repetirlo mil millones de veces por cada tipo de arena que está creando.
Ahora, si lees las explicaciones anteriores, quizás te resulte más fácil de entender. Espero que esta explicación te haya ayudado.
fuente
Esto me recuerda el patrón de diseño de la estrategia . Tenga en cuenta que el enlace al que apunté incluye código Java para el patrón.
Obviamente, uno podría realizar "Ejecutar alrededor" haciendo un código de inicialización y limpieza y simplemente pasando una estrategia, que siempre estará envuelta en un código de inicialización y limpieza.
Al igual que con cualquier técnica utilizada para reducir la repetición del código, no debe usarlo hasta que tenga al menos 2 casos donde lo necesite, tal vez incluso 3 (al principio de YAGNI). Tenga en cuenta que la eliminación de la repetición del código reduce el mantenimiento (menos copias de código significa menos tiempo dedicado a copiar arreglos en cada copia), pero también aumenta el mantenimiento (más código total). Por lo tanto, el costo de este truco es que está agregando más código.
Este tipo de técnica es útil para algo más que la inicialización y la limpieza. También es bueno para cuando desee que sea más fácil llamar a sus funciones (por ejemplo, podría usarlo en un asistente para que los botones "siguiente" y "anterior" no necesiten declaraciones de casos gigantes para decidir qué hacer para ir a la página siguiente / anterior
fuente
Si quieres modismos geniales, aquí está:
fuente