From grimoire
Defines an algorithm skeleton in a base class with abstract steps for subclasses to override. Use when multiple classes share the same structure but differ in specific steps.
How this skill is triggered — by the user, by Claude, or both
Slash command
/grimoire:apply-template-method-patternThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Define the skeleton of an algorithm in a base class, deferring specific steps to subclasses — so subclasses can redefine parts of the algorithm without changing its overall structure.
Define the skeleton of an algorithm in a base class, deferring specific steps to subclasses — so subclasses can redefine parts of the algorithm without changing its overall structure.
Adopted by: Java's AbstractList (implements the full List contract based on
just size() and get() — subclasses provide those two methods, inheriting 30+ free
implementations), Django's class-based views (View.dispatch() is the template method
— subclasses override get(), post(), etc.), JUnit's test lifecycle
(setUp()/tearDown() are hook methods in the template), and Java's HttpServlet
(service() dispatches to overridable doGet()/doPost()).
Impact: GoF documents that Template Method is one of the most fundamental techniques
for code reuse via inheritance. Django's class-based views reduce view code by 60–80%
for standard CRUD operations — because the template (dispatch, render) is in the
base class and only the business logic step changes.
Why best: Code duplication — the alternative — copies the algorithm skeleton into
every subclass. A bug or enhancement to the skeleton requires editing every copy.
Template Method edits once; all subclasses inherit the fix.
Sources: Gamma et al. (1994) pp. 325–330; Django class-based views documentation;
Java AbstractList source
Skeleton (invariant): read data → process → format output → write result
Varying steps: how to read, how to process, how to format
from abc import ABC, abstractmethod
class ReportGenerator(ABC):
def generate(self, data_source: str) -> str:
"""Template method — defines the algorithm skeleton."""
raw_data = self._read_data(data_source)
processed = self._process(raw_data)
formatted = self._format(processed)
self._write(formatted)
return formatted
@abstractmethod
def _read_data(self, source: str) -> list: ...
@abstractmethod
def _process(self, data: list) -> dict: ...
@abstractmethod
def _format(self, data: dict) -> str: ...
def _write(self, output: str) -> None:
"""Hook — optional override. Default: print."""
print(output)
class CSVReportGenerator(ReportGenerator):
def _read_data(self, source: str) -> list:
import csv
with open(source) as f:
return list(csv.reader(f))
def _process(self, data: list) -> dict:
return {"rows": len(data), "cols": len(data[0]) if data else 0}
def _format(self, data: dict) -> str:
return f"CSV Report: {data['rows']} rows × {data['cols']} columns"
class JSONReportGenerator(ReportGenerator):
def _read_data(self, source: str) -> list:
import json
with open(source) as f:
return json.load(f)
def _process(self, data: list) -> dict:
return {"count": len(data)}
def _format(self, data: dict) -> str:
return f"JSON Report: {data['count']} records"
@abstractmethod): must be overridden — they have no defaultdef _write(self, output: str) -> None:
print(output) # hook — override to write to file, send email, etc.
The template method defines the algorithm contract. Subclasses should override only the steps, not the skeleton.
def generate(self, data_source: str) -> str:
# Python has no `final` keyword — document explicitly
# Subclasses: override _read_data, _process, _format, _write only
...
apply-strategy-pattern is correct (composition over inheritance).Subclass overriding the template method. If CSVReportGenerator.generate() overrides ReportGenerator.generate(), the skeleton is broken. The template method is the invariant; override only the abstract steps.
Too many abstract steps. If every step is abstract, there's no shared skeleton — subclasses duplicate the orchestration. Keep the skeleton meaningful (3–6 steps); if one step always needs overriding alone, consider a Strategy for that step.
Confusing Template Method with Strategy. Template Method uses inheritance — subclass IS-A base. Strategy uses composition — context HAS-A strategy. If the "algorithm" varies per instance at runtime, use Strategy. If it varies per class, use Template Method.
npx claudepluginhub jeffreytse/grimoire --plugin grimoireGenerates Template Method pattern for PHP 8.4: abstract algorithm skeleton with customizable steps, concrete implementations, hooks, optional value objects, and unit tests. For reusable algorithms with variants like data processing.
Implements the Template Method design pattern to define algorithm skeletons in base classes with abstract steps filled by subclasses. Useful for parsers, importers, and test frameworks.
Encapsulates interchangeable algorithms in separate classes, enabling runtime swapping without conditional logic. Useful when multiple behaviors exist for a task.