Template Method Pattern
Part of the Object Oriented Programming section of Coddy's PHP journey — lesson 78 of 91.
The Template Method Pattern is a behavioral design pattern that defines the skeleton of an algorithm in a base class, allowing subclasses to override specific steps without changing the overall structure. The base class controls the workflow, while subclasses customize individual pieces.
Consider building different types of documents.
Every document follows the same process: create header, add content, create footer. But the specifics of each step vary by document type. The template method defines this sequence, while subclasses implement the details.
<?php
abstract class DocumentGenerator {
// The template method - defines the algorithm structure
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Steps to be implemented by subclasses
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();
Output:
<html><head></head><body><p>Hello World</p></body></html>
=== DOCUMENT ===
Hello World
=== END ===Notice the final keyword on the template method. This prevents subclasses from changing the algorithm's structure. The pattern is ideal when you have multiple classes that follow the same workflow but differ in implementation details. Adding a new document type means creating a new subclass without touching existing code.
Challenge
EasyLet's build a report generation system using the Template Method Pattern. Different types of reports follow the same structure — a title section, data section, and summary section — but each report type formats these sections differently. The template method will define this workflow while subclasses customize each step.
You'll organize your code across four files:
ReportGenerator.php— Create an abstractReportGeneratorclass that defines the skeleton of the report generation algorithm. Your class should:- Accept a report title in its constructor (use constructor promotion)
- Have a
finalpublic methodgenerate(): stringthat calls three steps in order:createTitle(),createBody(), andcreateSummary(), concatenating their results - Declare three abstract protected methods that subclasses must implement:
createTitle(): string,createBody(): string, andcreateSummary(): string
HtmlReport.php— Include the ReportGenerator file and create anHtmlReportclass that extends it. This report formats output as HTML:createTitle()returns"<h1>[title]</h1>"createBody()returns"<p>Report data goes here</p>"createSummary()returns"<footer>End of report</footer>"
PlainTextReport.php— Include the ReportGenerator file and create aPlainTextReportclass that extends it. This report uses simple text formatting:createTitle()returns"### [title] ###\n"createBody()returns"Report data goes here\n"createSummary()returns"--- End of report ---"
main.php— Include both report files. You'll receive two inputs: a report type ("html"or"text") and a report title.Based on the report type, create the appropriate report generator with the given title. Call
generate()and print the complete report.
The Template Method Pattern ensures all reports follow the same three-step structure while allowing each report type to format its sections uniquely. The final keyword on generate() prevents subclasses from altering the algorithm's sequence — they can only customize individual steps.
Cheat sheet
The Template Method Pattern defines the skeleton of an algorithm in a base class, allowing subclasses to override specific steps without changing the overall structure.
The base class contains a template method that controls the workflow sequence. This method is typically marked as final to prevent subclasses from altering the algorithm's structure.
Subclasses implement abstract methods to customize individual steps of the algorithm.
<?php
abstract class DocumentGenerator {
// Template method - defines algorithm structure
public final function generate(): string {
$output = $this->createHeader();
$output .= $this->createContent();
$output .= $this->createFooter();
return $output;
}
// Abstract steps for subclasses to implement
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();
Key characteristics:
- The template method is marked
finalto prevent modification of the algorithm structure - Abstract methods define customization points for subclasses
- Ideal when multiple classes follow the same workflow but differ in implementation details
- Adding new variants requires only creating new subclasses without modifying existing code
Try it yourself
<?php
require_once 'HtmlReport.php';
require_once 'PlainTextReport.php';
// Read input
$reportType = trim(fgets(STDIN));
$reportTitle = trim(fgets(STDIN));
// TODO: Based on the report type ("html" or "text"),
// create the appropriate report generator with the given title
// TODO: Call generate() and print the complete report
?>This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe $this KeywordMethodsPropertiesConstructor (__construct)Destructor (__destruct)Recap - Simple Calculator4Inheritance
Basic InheritanceThe parent:: KeywordMethod OverridingThe final KeywordAbstract ClassesRecap - Employee Hierarchy7Encapsulation
Public, Protected, PrivateAccess Modifiers in DepthGetters and SettersInformation HidingConstructor Promotion (8.0)Recap - Student Records System10Advanced OOP Concepts
Composition vs InheritanceDependency InjectionAnonymous ClassesEnums (PHP 8.1)Fibers (PHP 8.1)Object Cloning Deep DiveGenerators & Iterators13Design Patterns Part 2
Command PatternAdapter PatternDecorator PatternTemplate Method PatternState PatternComposite PatternRepository Pattern2Namespaces & Autoloading
Introduction to NamespacesThe use KeywordPSR-4 Autoloading StandardComposer AutoloaderRecap - Organized Project5Interfaces & Contracts
Introduction to InterfacesImplementing InterfacesMultiple Interface ImplementInterface vs Abstract ClassType Hinting with InterfacesRecap - Shape Calculator8Magic Methods
Magic Methods Introduction__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Object Cloning__serialize & __unserializeRecap - Custom Collection11Type System & Error Handling
Type DeclarationsNullable TypesUnion & Intersection TypesException ClassesCustom Exception HierarchyTry, Catch, FinallyRecap - Form Validator14Project: Library Management
Project OverviewBook and User Classes3Class Properties
Instance vs Static PropertiesConstants in ClassesStatic Methods & PropertiesPrivate & Protected PropertiesReadonly Properties (PHP 8.1)Recap - Bank Account Manager6Polymorphism
Method Overriding RevisitedPolymorphism via InterfacesType Hinting & Union TypesLate Static BindingRecap - Payment Processor9Traits
Introduction to TraitsUsing Multiple TraitsTrait Conflict ResolutionAbstract Methods in TraitsTraits vs Inheritance12Design Patterns Part 1
Intro to Design PatternsSingleton PatternFactory PatternObserver PatternStrategy Pattern