El patrón de diseño de la estrategia a menudo se considera como un sustituto de las funciones de primera clase en los idiomas que carecen de ellas.
Entonces, por ejemplo, digamos que desea pasar la funcionalidad a un objeto. En Java, tendría que pasar al objeto otro objeto que encapsule el comportamiento deseado. En un lenguaje como Ruby, simplemente pasaría la funcionalidad en forma de una función anónima.
Sin embargo, estaba pensando en ello y decidí que quizás la Estrategia ofrece más que una simple función anónima.
Esto se debe a que un objeto puede mantener un estado que existe independientemente del período en que se ejecuta su método. Sin embargo, una función anónima por sí sola solo puede mantener un estado que deja de existir en el momento en que la función finaliza la ejecución.
En un lenguaje orientado a objetos que admite funciones de primera clase, ¿el patrón de estrategia tiene alguna ventaja sobre el uso de funciones?
fuente
Respuestas:
Cuando el lenguaje admite referencias a la función ( Java lo hace desde la versión 8 ), a menudo son una buena alternativa para las estrategias, porque generalmente expresan lo mismo con menos sintaxis. Sin embargo, hay algunos casos en los que un objeto real puede ser útil.
Una interfaz de estrategia puede tener múltiples métodos. Tomemos una interfaz
RouteFindingStragegy
como ejemplo, que encapsula diferentes algoritmos de búsqueda de rutas. Podría declarar métodos comoRoute findShortestRoute(Node start, Node destination)
boolean doesRouteExist(Node start, Node destination)
Route[] findAllPossibleRoutes(Node start, Node destination)
Route findShortestRouteToClosestDestination(Node start, Node[] destinations)
Route findTravelingSalesmanRoute(Node[] stations)
que luego sería implementado por la estrategia. Algunos algoritmos de búsqueda de rutas pueden permitir optimizaciones internas para algunos de estos casos de uso y otros no, por lo que el implementador puede decidir cómo implementar cada uno de estos métodos.
Otro caso es cuando la estrategia tiene un estado interno. Claro, en algunos idiomas los cierres pueden tener un estado interno, pero cuando este estado interno se vuelve muy complejo, a menudo se vuelve más elegante promover el cierre a una clase completa.
fuente
No es cierto que una función anónima solo pueda mantener un estado que deja de existir cuando la función finaliza la ejecución.
Tome el siguiente ejemplo en Common Lisp:
Esta función toma una lista de cadenas y antepone un contador a cada elemento de la lista. Entonces, por ejemplo, invocando
da
La función
number-strings
utiliza internamente una función anónima con una variablecounter
que contiene el estado (el valor actual del contador) que se reutiliza cada vez que se invoca la función.En general, puede pensar en un cierre como un objeto con un solo método. Alternativamente, un objeto es una colección de cierres que comparten las mismas variables cerradas. Por lo tanto, no estoy seguro de si hay casos en los que necesite usar un objeto en lugar de un cierre: diría que ambas son formas de ver el mismo patrón desde diferentes perspectivas.
En particular, el patrón de estrategia requiere un objeto con un solo método, por lo que un cierre debería hacer el trabajo. Pero, como Philipp ha observado en su respuesta, dependiendo de las circunstancias (estado complejo) y los lenguajes de programación, puede obtener una solución más elegante mediante el uso de objetos.
fuente
let
ay luego definir mi cierre dentro de él. Básicamente, habría definido un objeto con un método sobre la marcha. En otro lenguaje (por ejemplo, Java) podría ser más conveniente (sintácticamente más simple) definir un objeto apropiado para mantener el estado. Entonces, decidiría de un caso a otro.El hecho de que dos diseños puedan resolver el mismo problema no significa que sean sustituciones directas entre sí.
Si necesita realizar un seguimiento del estado en un programa funcional, no mute una variable cerrada, incluso si el idioma lo permite. Arregla para llamar a una función que toma un estado como argumento y devuelve el nuevo estado como su valor de retorno.
Su arquitectura se verá muy diferente, pero logrará el mismo objetivo. No intente forzar los patrones de un paradigma directamente sobre el otro.
fuente
La estrategia es un concepto , una receta útil para resolver un problema particular y recurrente. No es una construcción de lenguaje, ni se trata de ninguna forma de implementación . Se puede usar un cierre para implementar la Estrategia un día y Observador al día siguiente.
El término Estrategia es principalmente útil en conversaciones con otros programadores para expresar de manera concisa su intención. No hay nada mágico al respecto.
fuente