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, 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 piezas individuales.
Considera crear diferentes tipos de documentos.
Cada documento sigue el mismo proceso: crear el encabezado, añadir el contenido y crear el pie de página. Pero los detalles de cada paso varían según el tipo de documento. El método plantilla define esta secuencia, mientras que las subclases implementan los detalles.
<?php
abstract class DocumentGenerator {
// El método plantilla - define la estructura del algoritmo
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Pasos a implementar 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();
Salida:
<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 algorithm. El patrón es ideal cuando tienes varias clases que siguen el mismo flujo de trabajo, pero difieren en los detalles de implementación. Añadir un nuevo tipo de documento implica crear una nueva subclase sin modificar el código existente.
Desafío
FácilConstruyamos un sistema de generación de informes utilizando el patrón Template Method. Los distintos 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 da formato a estas secciones de manera diferente. El método plantilla definirá este flujo de trabajo, mientras que las subclases personalizarán cada paso.
Organizarás tu código en cuatro archivos:
ReportGenerator.php: Crea una clase abstractaReportGeneratorque 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
finalgenerate(): stringque llame a tres pasos en orden:createTitle(),createBody()ycreateSummary(), concatenando sus resultados - Declarar tres métodos protegidos abstractos que las subclases deben implementar:
createTitle(): string,createBody(): stringycreateSummary(): string
HtmlReport.php: Incluye el archivo ReportGenerator y crea una claseHtmlReportque lo extienda. Este informe da formato a la salida como HTML:createTitle()devuelve"<h1>[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 clasePlainTextReportque lo extienda. Este informe utiliza un formato de texto sencillo:createTitle()devuelve"### [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.Según el tipo de informe, crea el generador de informes apropiado con el título proporcionado. Llama a
generate()e imprime el informe completo.
El patrón Template Method garantiza que todos los informes sigan la misma estructura de tres pasos, al tiempo que permite que cada tipo de informe dé un formato único a sus secciones. La palabra clave final en generate() impide que las subclases modifiquen la secuencia del algoritmo. Solo pueden personalizar pasos individuales.
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"),
// crea el generador de informes apropiado con el título dado
// TODO: Llama a generate() e imprime el informe completo
?>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 la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - Calculadora de formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeRepaso: colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online