Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Método plantilla Python: Profundizando en las clases

Ya conocemos conceptos clave como herencia y clases en Python. Ahora exploraremos un patrón de diseño muy útil en programación orientada a objetos: el método plantilla(template method).

Este patrón nos da una estructura general de cómo hacer las cosas, dejando algunos pasos para que las clases hijas los completen. En esta lección veremos cómo funciona y cómo nos ayuda a evitar duplicar código.


¿Qué es el método plantilla?

La idea detrás del método plantilla es que una clase base define la estructura general de un algoritmo (o de un comportamiento), pero deja algunas partes sin implementar, para que sus clases hijas completen esos pasos según lo que necesiten hacer.

Esto se puede lograr gracias a "vinculación tardía". Suena complicado, pero la idea es simple: cuando llamamos a un método desde la clase base, Python no sabe todavía qué versión exacta del método se está ejecutando. Por eso, si una clase hija implementa su propia versión del método, esa es la versión que se va a usar.

Veámoslo paso a paso con un ejemplo real.


Ejemplo: Generar HTML con clases

Imagina que estás creando un sistema para construir elementos HTML. Sabemos que la mayoría de las etiquetas HTML tienen una forma parecida: atributo(s) + contenido + etiquetas de apertura y cierre.

Un ejemplo sencillo de etiqueta en HTML sería:

<a href="https://python.org">Enlace a Python</a>

Ahora veamos cómo podríamos representarlo con clases en Python.


1. Primer diseño: cada clase hace todo

Iniciamos con una clase específica que genera un elemento <a> (enlace):

class HTMLAnchorElement:
    def __str__(self):
        attr_line = self.stringify_attributes()  # Método común
        body = self.get_text_content()           # Método común
        return f'<a{attr_line}>{body}</a>'

En este código usamos dos métodos:

  • stringify_attributes(): arma los atributos como href="...".
  • get_text_content(): devuelve el texto dentro de la etiqueta.

Hasta aquí todo bien. Pero si luego queremos crear una clase para <p>, <div>, <h1>, etc., vamos a terminar copiando y pegando casi lo mismo, solo cambiando el nombre de la etiqueta.

Entonces, mejoramos el diseño.


2. Separar lo común en una clase base

Creamos una clase HtmlElement que define el método común para generar la etiqueta, y que delega a los hijos el nombre del tag:

class HtmlElement:
    def __str__(self):
        attr_line = self.stringify_attributes()
        body = self.get_text_content()
        tag_name = self.get_tag_name()  # Este método se define en los hijos
        return f"<{tag_name} {attr_line}>{body}</{tag_name}>"

Y ahora, las clases hijas se enfocan solo en lo que las diferencia: el nombre de la etiqueta.

class HtmlAnchorElement(HtmlElement):
    def get_tag_name(self):
        return "a"  # Devuelve el nombre del tag

Así hacemos que str() se herede, y cada hijo se encarga solo de su parte.


Pero, ¿qué pasa con los tags que no tienen contenido?

Hay etiquetas en HTML que no tienen cuerpo, por ejemplo:

<hr />
<br />
<img src="image.jpg" />

Este tipo de elementos se conocen como "etiquetas individuales" (single elements). Y el código anterior, que espera que haya contenido, no funciona bien para ellos.


Solución: Dividir en clases para etiquetas de apertura/cierre y etiquetas individuales

Para manejar esto, creamos dos nuevos tipos de clases que heredan de HtmlElement:

  • HtmlPairElement: para etiquetas con apertura y cierre.
  • HtmlSingleElement: para etiquetas individuales.

Clase para etiquetas individuales

class HtmlSingleElement(HtmlElement):
    def __str__(self):
        attr_line = self.stringify_attributes()
        tag_name = self.get_tag_name()
        return f"<{tag_name} {attr_line} />"

Clase para etiquetas con cuerpo

class HtmlPairElement(HtmlElement):
    def __str__(self):
        attr_line = self.stringify_attributes()
        body = self.get_text_content()
        tag_name = self.get_tag_name()
        return f"<{tag_name} {attr_line}>{body}</{tag_name}>"

Uso en clases hijas:

class HtmlImageElement(HtmlSingleElement):
    def get_tag_name(self):
        return "img"

class HtmlParagraphElement(HtmlPairElement):
    def get_tag_name(self):
        return "p"

De esta forma, cada clase maneja su propio tipo de etiqueta, y evitamos duplicar lógica en cada una.


¿Qué ganamos con esto?

El uso del método plantilla nos ayudó a:

  • Separar lo que es común de lo que es específico.
  • Organizar mejor nuestro código.
  • Reducir repeticiones en clases hijas.
  • Hacer que nuestro código sea más fácil de mantener.

Veamos una comparación final.

Elemento HTML Descripción / Tipo
HtmlElement Base — Lógica general
HtmlSingleElement Subclase — Formato de etiqueta individual
HtmlPairElement Subclase — Formato de etiqueta con cuerpo
HtmlAnchorElement Especialización — get_tag_name()
HtmlImageElement Especialización — get_tag_name()

Resumen

  • El patrón método plantilla permite definir una estructura común en una clase base, y delegar los detalles a clases hijas.
  • Se apoya en el mecanismo de vinculación tardía de Python, que decide qué método ejecutar en tiempo de ejecución.
  • Aplicamos este patrón creando una clase base HtmlElement, con métodos que llaman a otros métodos que se definen en las clases hijas.
  • Para adaptar el comportamiento a diferentes tipos de etiquetas HTML, usamos subclases como HtmlSingleElement y HtmlPairElement.
  • Evitar código duplicado hace que nuestro programa sea más claro, limpio y fácil de mantener.

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY