¿Puede alguien explicarme cuál es la diferencia entre el patrón de método de plantilla y el patrón de estrategia?
Por lo que puedo decir, son 99% iguales, la única diferencia es que el patrón del método de plantilla tiene una clase abstracta como la clase base, mientras que la clase de estrategia utiliza una interfaz implementada por cada clase de estrategia concreta.
Sin embargo, en lo que respecta al cliente , se consume exactamente de la misma manera: ¿es esto correcto?
Respuestas:
La principal diferencia entre los dos es cuando se elige el algoritmo concreto.
Con el patrón de método de plantilla, esto sucede en tiempo de compilación al subclasificar la plantilla. Cada subclase proporciona un algoritmo concreto diferente al implementar los métodos abstractos de la plantilla. Cuando un cliente invoca métodos de la interfaz externa de la plantilla, la plantilla llama a sus métodos abstractos (su interfaz interna) según sea necesario para invocar el algoritmo.
Por el contrario, el patrón de estrategia permite elegir un algoritmo en tiempo de ejecución mediante contención . Los algoritmos concretos se implementan mediante clases o funciones separadas que se pasan a la estrategia como un parámetro para su constructor o para un método de establecimiento. El algoritmo elegido para este parámetro puede variar dinámicamente según el estado o las entradas del programa.
En resumen:
fuente
if (config.useAlgoA) impl = new AlgoA() else impl = new AlgoB()
), por lo que esta respuesta es incorrecta.new ConcreteAlgorithm1()
versusnew ConcreteAlgorithm2()
. Obviamente, la elección ocurre en tiempo de ejecución (hacer una elección de algoritmo en tiempo de compilación significaría codificarlo). La principal diferencia entre los dos es cómo se implementa el algoritmo concreto. ¿Se implementa como una subclase o como una interfaz separada? El primero es una plantilla. Este último es una estrategia. La diferencia puede resumirse como composición versus herencia, que es un tema común del libro GoF.El patrón de plantilla se usa cuando una operación particular tiene algunos comportamientos invariables que se pueden definir en términos de otros comportamientos primitivos variables. La clase abstracta define los comportamientos invariantes, mientras que las clases implementadoras definen los métodos dependientes.
En una estrategia, las implementaciones de comportamiento son independientes: cada clase de implementación define el comportamiento y no hay código compartido entre ellas. Ambos son patrones de comportamiento y, como tales, los clientes los consumen de la misma manera. Por lo general, las estrategias tienen un único método público: el
execute()
método, mientras que las plantillas pueden definir un conjunto de métodos públicos, así como un conjunto de primitivas privadas de soporte que las subclases deben implementar.Los dos patrones podrían usarse fácilmente juntos. Es posible que tenga un patrón de estrategia donde varias implementaciones pertenecen a una familia de estrategias implementadas usando un patrón de plantilla.
fuente
Creo que los Diagramas de clase de ambos patrones muestran las diferencias.
Estrategia
Encapsula un algoritmo dentro de una clase
Enlace a imagen
Método de plantilla
Aplaza los pasos exactos de un algoritmo a una subclase
Link to Image
fuente
Probablemente te refieres al patrón de método de plantilla. Tienes razón, atienden necesidades muy similares. Diría que es mejor usar el método de plantilla en los casos en que tiene un algoritmo de "plantilla" que tiene pasos definidos donde las subclases anulan estos pasos para cambiar algunos detalles. En el caso de la estrategia, debe crear una interfaz y, en lugar de la herencia, está utilizando la delegación. Diría que es un patrón un poco más poderoso y quizás mejor de acuerdo con los principios de inversión de dependencia DIP. Es más poderoso porque define claramente una nueva abstracción de la estrategia, una forma de hacer algo que no se aplica al método de plantilla. Entonces, si esta abstracción tiene sentido, úsela. Sin embargo, el uso del método de plantilla puede proporcionarle diseños más simples en casos simples, lo que también es importante. Considere qué palabras se ajustan mejor: ¿tienes un algoritmo de plantilla? ¿O es la clave aquí que tienes una abstracción de la estrategia: una nueva forma de hacer algo?
Ejemplo de un método de plantilla:
Aquí hereda de la aplicación y sustituye lo que se hará exactamente en init, run y done.
Ejemplo de una estrategia:
Aquí, al escribir un comparador, no se hereda de una matriz. La matriz delega el algoritmo de comparación a un comparador.
fuente
Similitudes
Los patrones de estrategia y método de plantilla tienen muchas similitudes entre ellos. Tanto los patrones de método de Estrategia como los de Plantilla se pueden usar para satisfacer el Principio de Cerrado Abierto y hacer que el módulo de software sea fácil de extender sin cambiar su código. Ambos patrones representan la separación de la funcionalidad genérica de la implementación detallada de esa funcionalidad. Sin embargo, difieren un poco en términos de granularidad que ofrecen.
Las diferencias
Estas son algunas de las diferencias que he observado al estudiar estos dos patrones:
La imagen está tomada del blog mordido .
fuente
Herencia versus agregación (is-a versus has-a). Son dos formas de lograr el mismo objetivo.
Esta pregunta muestra algunas compensaciones entre las opciones: Herencia versus Agregación
fuente
Ambos son muy similares y el código del cliente los consume de manera similar. A diferencia de lo que dice la respuesta más popular anterior, ambas permiten la selección de algoritmos en tiempo de ejecución .
La diferencia entre los dos es que, si bien el patrón de estrategia permite que diferentes implementaciones utilicen formas completamente diferentes de lograr el resultado deseado, el patrón del método de plantilla especifica un algoritmo general (el método de "plantilla") que se utiliza para lograr el resultado: - la única opción que queda para las implementaciones específicas (subclases) son ciertos detalles de dicho método de plantilla. Esto se hace haciendo que el método de plantilla haga llamadas a uno o más resúmenes métodos que las subclases anulan (es decir, implementan), a diferencia del método de plantilla que no es abstracto y que las subclases no anulan .
El código del cliente realiza una llamada al método de plantilla utilizando una referencia / puntero del tipo de clase abstracta que apunta a una instancia de una de las subclases concretas que se puede determinar en tiempo de ejecución al igual que al usar el Patrón de estrategia.
fuente
Método de plantilla:
Estructura de plantilla_método :
Estrategia:
Estructura de estrategia :
Eche un vistazo a los métodos de plantilla y artículos de estrategia para una mejor comprensión.
Artículos Relacionados:
El patrón de diseño de plantilla en JDK no pudo encontrar un método que definiera un conjunto de métodos para ejecutar en orden
Ejemplo del mundo real del patrón de estrategia
fuente
No, no se consumen necesariamente de la misma manera. El patrón de "método de plantilla" es una forma de proporcionar "orientación" a futuros implementadores. Les está diciendo, "Todos los objetos Persona deben tener un Número de Seguro Social" (ese es un ejemplo trivial pero transmite la idea correctamente).
El patrón de estrategia permite que múltiples implementaciones posibles se puedan activar y desactivar. No se implementa (generalmente) a través de la herencia, sino que deja que la persona que llama pase la implementación deseada. Un ejemplo podría ser permitir que se proporcione a ShippingCalculator una de varias formas diferentes de calcular los impuestos (una implementación NoSalesTax y una implementación PercentageBasedSalesTax, tal vez).
Entonces, a veces, el cliente le dirá al objeto qué estrategia usar. Como en
Pero el cliente nunca haría eso por un objeto basado en el Método de plantilla. De hecho, es posible que el cliente ni siquiera sepa que un objeto se basa en el Método de plantilla. Esos métodos abstractos en el patrón Método de plantilla podrían incluso estar protegidos, en cuyo caso el cliente ni siquiera sabría que existen.
fuente
Te sugiero que leas este artículo. Explica las diferencias en un ejemplo de caso real.
Cita del articulo
fuente
El patrón de plantilla es similar al patrón de estrategia. Estos dos patrones difieren en alcance y metodología.
La estrategia se usa para permitir que las personas que llaman varíen un algoritmo completo, como cómo calcular diferentes tipos de impuestos, mientras que el Método de plantilla se usa para variar los pasos en un algoritmo. Debido a esto, la estrategia es más gruesa. La plantilla permite controles más precisos en la secuencia de operaciones y, sin embargo, permite que las implementaciones de estos detalles varíen.
La otra diferencia principal es que la Estrategia usa la delegación, mientras que el Método de la Plantilla usa la herencia. En Estrategia, el algoritmo se delega a la otra clase xxxStrategy a la que el sujeto tendrá una referencia, pero con Plantilla subclasifica la base y anula los métodos para realizar cambios.
de http://cyruscrypt.blogspot.com/2005/07/template-vs-strategy-patterns.html
fuente
En el patrón de estrategia, las subclases ejecutan el programa y controlan el algoritmo. Aquí el código se duplica en las subclases. El conocimiento del algoritmo y cómo implementarlo se distribuye en muchas clases.
En el patrón de plantilla, la clase base tiene algoritmo. Maximiza la reutilización entre las subclases. Dado que el algoritmo se encuentra en un lugar, la clase base lo protege.
fuente
fuente
Patrón de plantilla:
El método de plantilla consiste en permitir que las subclases redefinan ciertos pasos del algoritmo, sin cambiar la estructura principal y los pasos del algoritmo, definidos en la clase base. El patrón de plantilla generalmente usa la herencia, por lo que se puede proporcionar una implementación genérica de algoritmos en la clase base, que la subclase podría optar por anular si es necesario.
Tenga en cuenta que en el código anterior, los pasos del algoritmo go () siempre serán los mismos, pero las subclases pueden definir una receta diferente para realizar un paso en particular.
Patrón de estrategia:
El patrón de estrategia consiste en permitir que el cliente seleccione la implementación de algoritmos concretos en tiempo de ejecución. Todos los algoritmos son aislados e independientes, pero implementan una interfaz común y no existe la noción de definir pasos particulares dentro del algoritmo.
Para obtener el código fuente completo, consulte mi repositorio github .
fuente
La estrategia se expone como un método de interfaz y plantilla como la clase abstracta. Esto generalmente se usa mucho en frameworks. Por ejemplo, la clase MessageSource de Spring Framework es una interfaz de estrategia para resolver mensajes. El cliente utiliza una implementación particular (estrategia) de esta interfaz.
Y la implementación abstracta de la misma interfaz AbstractMessageSource, que tiene una implementación común de resolución de mensajes y expone el método abstracto resolveCode () para que las subclases puedan implementarlos a su manera. AbstractMessageSource es un ejemplo de método de plantilla.
http://docs.spring.io/spring/docs/4.1.7.RELEASE/javadoc-api/org/springframework/context/support/AbstractMessageSource.html
fuente
En el método de plantilla de este patrón de diseño, las subclases pueden anular uno o más pasos del algoritmo para permitir diferentes comportamientos y garantizar que se siga el algoritmo general (Wiki).
El método de plantilla de nombre de patrón significa lo que es. Digamos que tenemos un método CalculateSomething () y queremos modelar este método. Este método se declarará en la clase base un método no virtual. Digamos que el método se ve así.
} La implementación del método Step1 y Step2 puede ser dada por clases derivadas.
En el Patrón de estrategia no hay una implementación proporcionada por la base (esta es la razón por la cual la base es realmente una interfaz en el diagrama de clases)
El ejemplo clásico es la clasificación. Según la cantidad de objetos que se deben ordenar, se crea la clase de algoritmo apropiada (fusión, burbuja, rápida, etc.) y se encapsula todo el algoritmo en cada clase.
¿Ahora podemos implementar la clasificación como un método de plantilla? Ciertamente puede, pero no encontrará mucho / ningún elemento en común para resumir y colocar en la implementación base. Por lo tanto, derrota el propósito del patrón de método de plantilla.
fuente