Menu
Coddy logo textTech

Patrón Template Method

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 78 de 91.

El Patrón Template Method 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. La clase base controla el flujo de trabajo, mientras que las subclases personalizan las piezas individuales.

Considera crear diferentes tipos de documentos.

Cada documento sigue el mismo proceso: crear el encabezado, añadir contenido, crear el pie de página. Pero los detalles de cada paso varían según el tipo de documento. El método de plantilla define esta secuencia, mientras que las subclases implementan los detalles.

<?php
abstract class DocumentGenerator {
    // El método de plantilla - define la estructura del algoritmo
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Pasos a ser implementados por las subclases
    abstract protected function createHeader(): string;
    abstract protected function createContent(): string;
    abstract protected function createFooter(): string;
}

class HtmlDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "<html><head></head><body>";
    }
    
    protected function createContent(): string {
        return "<p>Hello World</p>";
    }
    
    protected function createFooter(): string {
        return "</body></html>";
    }
}

class TextDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "=== DOCUMENT ===\n";
    }
    
    protected function createContent(): string {
        return "Hello World\n";
    }
    
    protected function createFooter(): string {
        return "=== END ===";
    }
}

$html = new HtmlDocument();
echo $html->generate() . "\n";

$text = new TextDocument();
echo $text->generate();

Resultado:

<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===

Observa la palabra clave final en el método de plantilla. Esto evita que las subclases cambien la estructura del algoritmo. El patrón es ideal cuando tienes múltiples clases que siguen el mismo flujo de trabajo pero difieren en los detalles de implementación. Añadir un nuevo tipo de documento significa crear una nueva subclase sin tocar el código existente.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de generación de informes utilizando el Patrón Template Method. Diferentes tipos de informes siguen la misma estructura — una sección de título, una sección de datos y una sección de resumen — pero cada tipo de informe formatea estas secciones de manera diferente. El método de plantilla definirá este flujo de trabajo mientras que las subclases personalizan cada paso.

Organizarás tu código en cuatro archivos:

  • ReportGenerator.php — Crea una clase abstracta ReportGenerator que defina el esqueleto del algoritmo de generación de informes. Tu clase debe:
    • Aceptar un título de informe en su constructor (utiliza la promoción de constructor)
    • Tener un método público final llamado generate(): string que llame a tres pasos en orden: createTitle(), createBody(), y createSummary(), concatenando sus resultados
    • Declarar tres métodos protegidos abstractos que las subclases deben implementar: createTitle(): string, createBody(): string, y createSummary(): string
  • HtmlReport.php — Incluye el archivo ReportGenerator y crea una clase HtmlReport que lo extienda. Este informe formatea la salida como HTML:
    • createTitle() devuelve "<h1>" . $this->title . "</h1>"
    • createBody() devuelve "<p>Report data goes here</p>"
    • createSummary() devuelve "<footer>End of report</footer>"
  • PlainTextReport.php — Incluye el archivo ReportGenerator y crea una clase PlainTextReport que lo extienda. Este informe utiliza un formato de texto simple:
    • createTitle() devuelve "### " . $this->title . " ###\n"
    • createBody() devuelve "Report data goes here\n"
    • createSummary() devuelve "--- End of report ---"
  • main.php — Incluye ambos archivos de informes. Recibirás dos entradas: un tipo de informe ("html" o "text") y un título de informe.

    Basándote en el tipo de informe, crea el generador de informes apropiado con el título dado. Llama a generate() e imprime el informe completo.

El Patrón Template Method asegura que todos los informes sigan la misma estructura de tres pasos, permitiendo al mismo tiempo que cada tipo de informe formatee sus secciones de manera única. La palabra clave final en generate() evita que las subclases alteren la secuencia del algoritmo — solo pueden personalizar los pasos individuales.

Hoja de referencia

El Patrón de Método de Plantilla 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 controla la secuencia del flujo de trabajo. Este método suele marcarse como final para evitar que las subclases alteren la estructura del algoritmo.

Las subclases implementan métodos abstractos para personalizar pasos individuales del algoritmo.

<?php
abstract class DocumentGenerator {
    // Método de plantilla - define la estructura del algoritmo
    public final function generate(): string {
        $output = $this->createHeader();
        $output .= $this->createContent();
        $output .= $this->createFooter();
        return $output;
    }
    
    // Pasos abstractos para que las subclases los implementen
    abstract protected function createHeader(): string;
    abstract protected function createContent(): string;
    abstract protected function createFooter(): string;
}

class HtmlDocument extends DocumentGenerator {
    protected function createHeader(): string {
        return "<html><head></head><body>";
    }
    
    protected function createContent(): string {
        return "<p>Hello World</p>";
    }
    
    protected function createFooter(): string {
        return "</body></html>";
    }
}

$html = new HtmlDocument();
echo $html->generate();

Características clave:

  • El método de plantilla se marca como final para evitar la modificación de la estructura del algoritmo
  • Los métodos abstractos definen puntos de personalización para las subclases
  • Ideal cuando múltiples clases siguen el mismo flujo de trabajo pero difieren en los detalles de implementación
  • Agregar nuevas variantes solo requiere crear nuevas subclases sin modificar el código existente

Pruébalo tú mismo

<?php

require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';

// Leer entrada
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));

// TODO: Basado en el tipo de informe ("html" o "text"),
// crear el generador de informes apropiado con el título dado

// TODO: Llamar a generate() e imprimir el informe completo

?>
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