Files
2024-10-20 10:22:52 +03:00

157 lines
5.6 KiB
Markdown

---
title: Template method
shortTitle: Template method
category: Behavioral
language: es
tag:
- Gang of Four
---
## Propósito
Define el esqueleto de un algoritmo en una operación, difiriendo algunos pasos a subclases. Plantilla
Método que permite a las subclases redefinir ciertos pasos de un algoritmo sin cambiar la estructura del algoritmo.
del algoritmo.
## Explicación
Ejemplo del mundo real
> Los pasos generales para robar un objeto son los mismos. Primero, eliges al objetivo, luego lo confundes...
> y finalmente, robas el objeto. Sin embargo, hay muchas maneras de implementar estos
> pasos.
En palabras sencillas
> El patrón Template Method esboza los pasos generales en la clase padre y deja que las implementaciones hijas concretas definan los detalles.
Wikipedia dice
> En programación orientada a objetos, el método de plantillas es uno de los patrones de diseño de comportamiento
> identificados por Gamma et al. en el libro Design Patterns. El método de plantilla es un método en una
> superclase, normalmente una superclase abstracta, y define el esqueleto de una operación en términos de
> una serie de pasos de alto nivel. Estos pasos son a su vez implementados por métodos de ayuda adicionales
> en la misma clase que el método de plantilla.
**Ejemplo programático**
Presentemos primero la clase de método de plantilla junto con sus implementaciones concretas.
Para asegurarse de que las subclases no sobrescriben el método de plantilla, el método de plantilla (en nuestro caso
método `steal`) debe ser declarado `final`, de lo contrario el esqueleto definido en la clase base podría
ser sobreescrito en subclases.
```java
@Slf4j
public abstract class StealingMethod {
protected abstract String pickTarget();
protected abstract void confuseTarget(String target);
protected abstract void stealTheItem(String target);
public final void steal() {
var target = pickTarget();
LOGGER.info("The target has been chosen as {}.", target);
confuseTarget(target);
stealTheItem(target);
}
}
@Slf4j
public class SubtleMethod extends StealingMethod {
@Override
protected String pickTarget() {
return "shop keeper";
}
@Override
protected void confuseTarget(String target) {
LOGGER.info("Approach the {} with tears running and hug him!", target);
}
@Override
protected void stealTheItem(String target) {
LOGGER.info("While in close contact grab the {}'s wallet.", target);
}
}
@Slf4j
public class HitAndRunMethod extends StealingMethod {
@Override
protected String pickTarget() {
return "old goblin woman";
}
@Override
protected void confuseTarget(String target) {
LOGGER.info("Approach the {} from behind.", target);
}
@Override
protected void stealTheItem(String target) {
LOGGER.info("Grab the handbag and run away fast!");
}
}
```
Aquí está la clase ladrón halfling que contiene el método de plantilla.
```java
public class HalflingThief {
private StealingMethod method;
public HalflingThief(StealingMethod method) {
this.method = method;
}
public void steal() {
method.steal();
}
public void changeMethod(StealingMethod method) {
this.method = method;
}
}
```
Y por último, mostramos cómo el ladrón halfling utiliza los diferentes métodos de robo.
```java
var thief = new HalflingThief(new HitAndRunMethod());
thief.steal();
thief.changeMethod(new SubtleMethod());
thief.steal();
```
## Diagrama de clases
![alt text](./etc/template_method_urm.png "Template Method")
## Aplicabilidad
El patrón Template Method debería utilizarse
* Para implementar las partes invariantes de un algoritmo una vez y dejar que las subclases implementen el comportamiento que puede variar.
* Cuando el comportamiento común entre subclases debe ser factorizado y localizado en una clase común para evitar la duplicación de código. Este es un buen ejemplo de "refactorizar para generalizar", tal y como lo describen Opdyke y Johnson. Primero se identifican las diferencias en el código existente y luego se separan las diferencias en nuevas operaciones. Por último, se sustituye el código diferente por un método de plantilla que llama a una de estas nuevas operaciones
* Para controlar las extensiones de las subclases. Puede definir un método de plantilla que llame a operaciones "gancho" en puntos específicos, permitiendo así extensiones sólo en esos puntos
## Tutoriales
* [Template-method Pattern Tutorial](https://www.journaldev.com/1763/template-method-design-pattern-in-java)
## Usos conocidos
* [javax.servlet.GenericServlet.init](https://jakarta.ee/specifications/servlet/4.0/apidocs/javax/servlet/GenericServlet.html#init--):
El método `GenericServlet.init(ServletConfig config)` llama al método sin parámetros `GenericServlet.init()` que está pensado para ser sobreescrito en subclases.
El método `GenericServlet.init(ServletConfig config)` es el método plantilla en este ejemplo.
## Créditos
* [Design Patterns: Elements of Reusable Object-Oriented Software](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59)
* [Head First Design Patterns: A Brain-Friendly Guide](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b)
* [Refactoring to Patterns](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7)