mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-14 18:58:44 +00:00
157 lines
5.6 KiB
Markdown
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
|
|
|
|

|
|
|
|
## 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)
|