Patrón Template Method
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 59 de 70.
El patrón Template Method es un patrón 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. La clase base controla el flujo de trabajo, mientras que las clases derivadas personalizan piezas individuales.
Este patrón utiliza herencia y métodos abstractos. La clase base contiene un "método de plantilla" que llama a una secuencia de pasos, algunos de los cuales son abstractos y deben ser implementados por las subclases:
public abstract class DataProcessor
{
// Método de plantilla - define la estructura del algoritmo
public void Process()
{
ReadData();
ProcessData();
SaveData();
}
protected abstract void ReadData();
protected abstract void ProcessData();
protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}
public class CsvProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading CSV file");
protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}
public class JsonProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading JSON file");
protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
protected override void SaveData() => Console.WriteLine("Saving to cloud");
}Cada subclase proporciona su propia implementación, mientras que la clase base impone el orden de las operaciones:
DataProcessor csv = new CsvProcessor();
csv.Process();
// Leyendo archivo CSV
// Analizando datos CSV
// Guardando en la ubicación predeterminada
DataProcessor json = new JsonProcessor();
json.Process();
// Leyendo archivo JSON
// Analizando datos JSON
// Guardando en la nubeEl patrón Template Method es ideal cuando varias clases comparten la misma estructura de algoritmo pero difieren en pasos específicos. Promueve la reutilización de código al colocar la lógica común en la clase base, permitiendo al mismo tiempo flexibilidad a través de métodos que se pueden sobrescribir.
Desafío
FácilVamos a construir un sistema de generación de informes utilizando el patrón Template Method. Diferentes tipos de informes (como informes de ventas e informes de inventario) comparten la misma estructura general: todos necesitan recopilar datos, darles formato y generar el resultado, pero cada tipo de informe maneja estos pasos de manera diferente.
Organizarás tu código en tres archivos:
ReportGenerator.cs: Crea una clase abstractaReportGeneratoren el espacio de nombresReporting. Esta clase base define el esqueleto del algoritmo de generación de informes a través de un método de plantilla llamadoGenerate(). El método debe llamar a tres pasos en orden:GatherData(),FormatReport()yOutputReport(). Haz queGatherData()yFormatReport()sean abstractos (cada tipo de informe los implementará de manera diferente), mientras queOutputReport()debe ser un método virtual con una implementación predeterminada que imprimaSending to default printer.ConcreteReports.cs: Crea dos clases de informes concretas en el mismo espacio de nombres que hereden deReportGenerator:SalesReport: implementaGatherData()para imprimirCollecting sales data from databaseyFormatReport()para imprimirFormatting as sales summaryInventoryReport: implementaGatherData()para imprimirScanning warehouse inventory,FormatReport()para imprimirFormatting as inventory list, y sobrescribeOutputReport()para imprimirSending to warehouse manager
Program.cs: Une todo creando instancias de informes y generándolos. El método de plantilla asegura que cada informe siga el mismo proceso de tres pasos, pero el comportamiento específico de cada paso varía según el tipo de informe.
Recibirás una entrada:
- El tipo de informe:
salesoinventory
Crea el generador de informes apropiado basado en la entrada y llama a su método Generate().
Por ejemplo, si la entrada es sales, la salida debería ser:
Collecting sales data from database
Formatting as sales summary
Sending to default printerSi la entrada es inventory, la salida debería ser:
Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse managerObserva cómo ambos informes siguen exactamente la misma estructura de algoritmo (recopilar, formatear, generar), pero la implementación de cada paso está personalizada. El SalesReport utiliza el comportamiento de salida predeterminado, mientras que InventoryReport lo sobrescribe, ¡demostrando cómo el patrón Template Method te permite controlar qué pasos son obligatorios de sobrescribir y cuáles pueden personalizarse opcionalmente!
Hoja de referencia
El patrón Template Method define el esqueleto de un algoritmo en una clase base, permitiendo que las subclases sobrescriban pasos específicos sin cambiar la estructura general.
La clase base contiene un "método de plantilla" que llama a una secuencia de pasos. Algunos pasos son abstractos (deben ser implementados por las subclases), mientras que otros pueden ser virtuales (opcionales de sobrescribir):
public abstract class DataProcessor
{
// Método de plantilla - define la estructura del algoritmo
public void Process()
{
ReadData();
ProcessData();
SaveData();
}
protected abstract void ReadData();
protected abstract void ProcessData();
protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}Las subclases proporcionan sus propias implementaciones mientras que la clase base impone el orden de las operaciones:
public class CsvProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading CSV file");
protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}
public class JsonProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading JSON file");
protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
protected override void SaveData() => Console.WriteLine("Saving to cloud");
}Uso:
DataProcessor csv = new CsvProcessor();
csv.Process();
// Reading CSV file
// Parsing CSV data
// Saving to default location
DataProcessor json = new JsonProcessor();
json.Process();
// Reading JSON file
// Parsing JSON data
// Saving to cloudEl patrón Template Method es ideal cuando múltiples clases comparten la misma estructura de algoritmo pero difieren en pasos específicos. Promueve la reutilización de código al colocar la lógica común en la clase base mientras permite flexibilidad a través de métodos sobrescribibles.
Pruébalo tú mismo
using System;
using Reporting;
class Program
{
public static void Main(string[] args)
{
string reportType = Console.ReadLine();
// TODO: Crear el generador de informes apropiado basado en reportType
// Si reportType es "sales", crear un SalesReport
// Si reportType es "inventory", crear un InventoryReport
// Luego llamar al método Generate() en el informe
}
}
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 externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantes