It depends on the use case.
If your scenario is creating a flexible template for the Type which is prone to modification afterwards, I guess a simple class inheritance is a suitable analogy.
If your scenario is forcing a type to follow a template (instead of using the template as just a default starting point), in OOP, there is a design pattern called template method (yeah the same name). In template method, a template class is first developed as a blueprint for other classes.
For example,
from abc import ABC, abstractmethod
class AbstractClass(ABC):
"""
A template for a general workflow, with specific steps left to be defined by subclasses.
"""
def template_method(self):
"""Template method that defines the algorithm's skeleton."""
self.step_one()
self.step_two()
self.step_three()
def step_one(self):
"""Concrete step."""
print("Step 1: Common behavior")
@abstractmethod
def step_two(self):
"""Abstract step that must be implemented by subclasses."""
pass
def step_three(self):
"""Concrete step."""
print("Step 3: Common behavior")
class ConcreteClass(AbstractClass):
"""Subclass implementing the abstract method."""
def step_two(self):
"""Implementation of the abstract step."""
print("Step 2: Subclass-specific behavior")
# Example usage:
obj = ConcreteClass()
obj.template_method()
In this pattern:
- The template_method() provides the overall structure of the process.
- Some steps, like step_two(), are abstract and must be provided by subclasses.
- Other steps, like step_one() and step_three(), have default implementations but can still be overridden if needed.