Patrón Template Method
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 73 de 87.
El Patrón de Método Plantilla es un patrón de diseño de comportamiento que define el esqueleto de un algoritmo en una clase base, permitiendo que las subclases sobrescriban pasos específicos sin cambiar la estructura general. Piensa en ello como en una receta: el proceso general de cocina permanece igual, pero los ingredientes o las técnicas individuales pueden variar.
El patrón utiliza una clase abstracta con un método plantilla que llama a una secuencia de pasos. Algunos pasos tienen implementaciones predeterminadas, mientras que otros son abstractos y deben ser implementados por las subclases:
abstract class DataProcessor {
// Método plantilla - define la estructura del algoritmo
public final void process() {
readData();
processData();
saveData();
}
abstract void readData();
abstract void processData();
// Implementación por defecto (método gancho)
void saveData() {
System.out.println("Saving to default location");
}
}
class CSVProcessor extends DataProcessor {
void readData() {
System.out.println("Reading CSV file");
}
void processData() {
System.out.println("Parsing CSV data");
}
}
class XMLProcessor extends DataProcessor {
void readData() {
System.out.println("Reading XML file");
}
void processData() {
System.out.println("Parsing XML data");
}
}El método de plantilla normalmente se marca como final para evitar que las subclases alteren la estructura del algoritmo. Cuando se llama, ejecuta la misma secuencia para todas las subclases:
DataProcessor csv = new CSVProcessor();
csv.process();
// Salida:
// Leyendo archivo CSV
// Analizando datos CSV
// Guardando en la ubicación predeterminadaEl patrón de método plantilla es ideal cuando tienes algoritmos que comparten la misma estructura, pero difieren en pasos específicos. Promueve la reutilización del código al colocar la lógica común en la clase base y permitir la personalización mediante la herencia.
Desafío
Fácil¡Construyamos un sistema de generación de documentos utilizando el patrón Template Method! Crearás un framework en el que distintos tipos de documentos (informes y facturas) siguen el mismo proceso de generación, pero personalizan pasos específicos. Esto es perfecto para situaciones en las que el flujo de trabajo general es fijo, pero los detalles varían según el tipo de documento.
Organizarás tu código en cuatro archivos:
DocumentGenerator.java: Crea la clase base abstracta que define el método plantilla. TuDocumentGeneratordebe tener:Un método
finalllamadogenerateDocument()que define el esqueleto del algoritmo llamando a tres pasos en orden:createHeader(),createBody()ycreateFooter().Dos métodos abstractos:
createHeader()ycreateBody(), que las subclases deben implementar.Un método de enlace
createFooter()con una implementación predeterminada que imprime--- End of Document ---.ReportGenerator.java: Crea una subclase concreta para generar informes. Debe recibir un título de informe (String) mediante su constructor.El método
createHeader()imprime=== REPORT: [title] ===El método
createBody()imprimeReport content goes here...Utiliza el pie de página predeterminado heredado.
InvoiceGenerator.java: Crea otra subclase concreta para generar facturas. Debe recibir un nombre de cliente (String) y un importe (double) mediante su constructor.El método
createHeader()imprime*** INVOICE ***El método
createBody()imprimeCustomer: [name]en una línea y, después,Amount Due: $[amount]en la línea siguiente (formatea el importe con dos decimales).Sobrescribe
createFooter()para imprimirThank you for your business!Main.java: ¡Integra tu sistema de métodos plantilla! Recibirás tres entradas: un título de informe (String), un nombre de cliente (String) y un importe de factura (double).Crea un
ReportGeneratorcon el título y llama agenerateDocument(). Imprime una línea vacía como separación. Después, crea unInvoiceGeneratorcon el nombre del cliente y el importe, y llama agenerateDocument().
Recibirás tres entradas en este orden: título del informe (String), nombre del cliente (String) e importe de la factura (double).
Por ejemplo, con las entradas Q4 Sales, Acme Corp y 1500.00, tu salida sería:
=== REPORT: Q4 Sales ===
Report content goes here...
--- End of Document ---
*** INVOICE ***
Customer: Acme Corp
Amount Due: $1500.00
Thank you for your business!Observa cómo ambos tipos de documentos siguen el mismo proceso de tres pasos definido en el método plantilla, pero cada uno personaliza los pasos de manera diferente. ReportGenerator utiliza el pie de página predeterminado, mientras que InvoiceGenerator proporciona el suyo propio. ¡Este es el poder de los métodos de enlace en el patrón Template Method!
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer entradas
String reportTitle = scanner.nextLine();
String customerName = scanner.nextLine();
double invoiceAmount = scanner.nextDouble();
// TODO: Crea un ReportGenerator con el título y llama a generateDocument()
// TODO: Imprime una línea vacía para separación
// TODO: Crea un InvoiceGenerator con el nombre del cliente y el monto, y llama a generateDocument()
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón IteratorPractica por tu cuenta: Compilador de Java online