Recientemente comencé a buscar patrones de diseño, y una cosa que estoy codificando se adaptaría perfectamente al patrón de estrategia, excepto por una pequeña diferencia.
Esencialmente, algunos (pero no todos) de mis algoritmos, necesitan que se les pase uno o dos parámetros adicionales.
Entonces, o bien necesito
- les paso un parámetro extra cuando invoco su método de cálculo
o
- almacénelos como variables dentro de la clase ConcreteAlgorithm y pueda actualizarlos antes de que llame al algoritmo.
¿Existe un patrón de diseño para esta necesidad / ¿Cómo podría implementar esto mientras me apego al Patrón de Estrategia?
He considerado pasar el objeto del cliente a todos los algoritmos, y almacenar las variables allí, luego usarlo solo cuando el algoritmo particular lo necesite. Sin embargo, creo que esto es difícil de manejar y derrota el punto del patrón de estrategia.
Para ser claros, estoy implementando en Java, por lo que no tengo el lujo de parámetros opcionales (lo que resolvería esto muy bien).
fuente
Respuestas:
Samuel, ¿es posible encapsular el parámetro que cada una de las estrategias toma en una clase común y luego extender esa clase de parámetro común para agregar más comportamiento que algunas de tus estrategias necesitan específicamente?
P.ej
Y luego, defina la jerarquía de la estrategia como:
llame a la estrategia anterior como:
myNormalStrategyInstance.myStrategyMethod(strategyParameter);
llame a la estrategia anterior pasando la
SpecialStrategyParameter
instancia en su lugar como:mySpecializedStrategy.myStrategyMethod(specialStrategyParameter);
Actualice si algo no está claro. Estaremos encantados de explicar / aclarar.
fuente
StrategyParameter
todos los parámetros posibles, como un DTO. Algunas implementaciones de la estrategia podrían ignorarlos. En algunos casos, ese es el mejor enfoque. El contexto es el rey para este tipo de problemas.Necesita aclarar su estrategia .
Todo depende de cómo uses tus algoritmos. Para que su clase de cliente use diferentes implementaciones de estrategia de manera intercambiable, todas deben tener una abstracción común . Si no siguen la misma interfaz, tal vez lo que necesita son diferentes abstracciones .
He usado estrategias configurables antes, donde parametrizas las clases concretas en la construcción:
Ahora, alguien aún necesita crear una instancia de esta clase y pasarla a su cliente. Pero su cliente solo necesita saber sobre la
Strategy
interfaz.También funciona si su método de estrategia toma parámetros, pero luego su cliente conoce esos parámetros y los pasa a todas las implementaciones con las que trabaja.
fuente
Mientras la firma se defina claramente en la interfaz, aún cumple con el patrón de Estrategia.
Los patrones tal como están escritos son la forma más simple y absoluta que aún exhibe el comportamiento esperado, por lo que puede embellecerlos siempre que mantenga la intención original. Eso, por supuesto, supone que quieres seguir el patrón. No tiene sentido usar un patrón si no encaja, o simplemente porque está allí, pero en tu caso creo que estás bien.
fuente
ampliando la respuesta anterior proporcionada por peakit: puede usar la abstracción. Estoy usando el código de Peakit aquí -
Interface MyStrategy { abstract void myStrategyMethod (parámetro StrategyParameter); }
La clase MyNormalStrategy extiende MyStrategy {anulación pública anula myStrategyMethod (parámetro StrategyParameter) {// implementa la lógica aquí}}
clase MySpecializedStrategy extiende MyStrategy {anulación pública void myStrategyMethod (parámetro StrategyParameter, ExtraStrategyParameter extraParameter) {// implementa la lógica aquí} }
Si entiendo su pregunta correctamente, ¿desea pasar un parámetro adicional a ciertos algoritmos, verdad? Por favor, avíseme si esto es lo que estaba buscando.
fuente
Si observa el libro de patrones de diseño, no está mal per se que exista alguna SimpleStrategy que use menos o ninguno de los parámetros pasados, o que los parámetros sean un único tamaño para todos / mínimo-multiplicador común. La elección del diseño aquí es si esto le perjudica en términos de procesamiento adicional que termina sin ser utilizado.
fuente