Menu
Coddy logo textTech

Patrón Template Method

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 97 de 110.

El patrón Template Method define el esqueleto de un algoritmo en una clase base, lo que permite que las subclases sobrescriban pasos específicos sin cambiar la estructura general. La clase base controla el flujo de trabajo, mientras que las subclases personalizan pasos individuales.

Este patrón utiliza la herencia: una clase abstracta define un método plantilla que llama a una secuencia de pasos, algunos de los cuales son abstractos (deben ser implementados por las subclases) y otros tienen implementaciones predeterminadas:

abstract class DataProcessor {
  // Método plantilla - define la estructura del algoritmo
  void process() {
    readData();
    processData();
    saveData();
  }

  void readData();      // Abstracto - las subclases deben implementar
  void processData();   // Abstracto - las subclases deben implementar

  void saveData() {     // Implementación por defecto
    print('Data saved to database');
  }
}

class CsvProcessor extends DataProcessor {
  @override
  void readData() => print('Reading CSV file');

  @override
  void processData() => print('Parsing CSV rows');
}

class JsonProcessor extends DataProcessor {
  @override
  void readData() => print('Reading JSON file');

  @override
  void processData() => print('Parsing JSON objects');

  @override
  void saveData() => print('Saved to cloud storage');
}

void main() {
  var csv = CsvProcessor();
  csv.process();
  // Leyendo archivo CSV
  // Analizando filas CSV
  // Datos guardados en la base de datos

  var json = JsonProcessor();
  json.process();
  // Leyendo archivo JSON
  // Analizando objetos JSON
  // Guardado en almacenamiento en la nube
}

El método process() es la plantilla: define el orden de las operaciones. Las subclases implementan readData() y processData() de manera diferente, y opcionalmente pueden redefinir saveData(). El beneficio principal es que la estructura del algoritmo se mantiene coherente en todas las implementaciones, al tiempo que permite flexibilidad en los pasos individuales.

challenge icon

Desafío

Fácil

¡Construyamos un sistema de generación de informes usando el patrón Template Method! Crearás un marco en el que diferentes tipos de informes siguen la misma estructura general, pero cada tipo de informe personaliza pasos específicos, como recopilar datos y dar formato a la salida.

Organizarás tu código en dos archivos:

  • report_generator.dart: Este archivo contiene tu clase base abstracta y las implementaciones concretas de los informes. Crea una clase base abstracta ReportGenerator con un método plantilla llamado generate() que define el flujo de trabajo de generación del informe en este orden: fetchData(), analyzeData(), formatReport() y deliver(). Los métodos fetchData() y formatReport() deben ser abstractos (cada tipo de informe los gestiona de forma diferente), mientras que analyzeData() debe imprimir Analyzing data... y deliver() debe imprimir Report delivered via email. como implementaciones predeterminadas. Después, crea dos clases concretas de informes:
    • SalesReport: su método fetchData() imprime Fetching sales data from database... y su método formatReport() imprime Formatting as bar charts and tables.
    • InventoryReport: su método fetchData() imprime Fetching inventory levels from warehouse..., su método formatReport() imprime Formatting as inventory list. y sobrescribe deliver() para imprimir Report sent to warehouse manager.
  • main.dart: Importa tu archivo del generador de informes y demuestra cómo el patrón Template Method mantiene coherente la estructura del algoritmo a la vez que permite la personalización. Crea un SalesReport y llama a su método generate(). Después, imprime una línea vacía como separación. Crea un InventoryReport y llama también a su método generate().

Observa cómo ambos informes siguen el mismo proceso de cuatro pasos, pero cada uno personaliza los pasos relevantes para su propósito específico. ¡InventoryReport incluso sobrescribe el método de entrega predeterminado para enviar los informes a un destinatario diferente!

Salida esperada:

Fetching sales data from database...
Analyzing data...
Formatting as bar charts and tables.
Report delivered via email.

Fetching inventory levels from warehouse...
Analyzing data...
Formatting as inventory list.
Report sent to warehouse manager.

Pruébalo tú mismo

import 'report_generator.dart';

void main() {
  // TODO: Crea un SalesReport y llama a su método generate()

  // TODO: Imprime una línea vacía para separación

  // TODO: Crea un InventoryReport y llama a su método generate()
}
quiz iconPonte a prueba

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

Practica por tu cuenta: Compilador de Dart online