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

Estado (Patrón de diseño) Python: Polimorfismo

Cuando estamos desarrollando un programa, muchas veces un objeto puede actuar diferente dependiendo de en qué situación o "estado" se encuentra. Por ejemplo, no es lo mismo lo que hace un teléfono cuando está apagado, a cuando está encendido con la pantalla bloqueada. Si tratamos de manejar todos esos cambios con muchos if, el código se vuelve complicado y difícil de entender.

Hoy vamos a aprender cómo usar el patrón de diseño Estado (State) para separar mejor esos comportamientos y hacer nuestro código más limpio, claro y fácil de mantener.


¿Qué es el patrón Estado?

Es una forma de organizar el código en situaciones donde un objeto tiene diferentes comportamientos, dependiendo del estado en el que se encuentra. En vez de tener muchos if para cada caso, creamos clases específicas para cada "estado".

Problema: Muchas condiciones, mucho lío

Ejemplo: un celular con pantalla táctil. Supongamos que puede estar en uno de estos tres estados:

Estado Descripción
Power Off Teléfono apagado. Nada responde.
Pantalla Apagada Encendido, pero la pantalla está inactiva.
Pantalla Encendida Encendido y pantalla activa. Reacciona a toques y gestos.

Veamos cómo podríamos programarlo de forma tradicional con muchas condiciones:

class MobileScreen:
    def __init__(self):
        self.power_on = False
        self.screen_on = False

    def power_on(self):
        self.power_on = True

    def touch(self):
        if not self.power_on:
            return  # No pasa nada

        if not self.screen_on:
            self.screen_on = True  # Activar pantalla

        self.notify('touch')  # Notificar a la app en uso

    def swipe(self):
        if not self.power_on or not self.screen_on:
            return

        self.notify('swipe')

Aunque esto funciona, puede salirse de control muy rápido a medida que agregamos más funciones (como desbloquear, abrir apps, bloquear, etc.).


Paso 1: Mejorar usando una sola variable de estado

Una forma de simplificar es dejar de usar varios flags (como power_on o screen_on) y reemplazarlos con una sola variable que diga directamente en qué estado está el objeto:

class MobileScreen:
    def __init__(self):
        self.state_name = 'power_off'

    def power_on(self):
        self.state_name = 'screen_disabled'

    def touch(self):
        if self.state_name == 'power_off':
            return

        if self.state_name == 'screen_disabled':
            self.state_name = 'screen_on'

        self.notify('touch')

    def swipe(self):
        if self.state_name != 'screen_on':
            return

        self.notify('swipe')

Esto ya mejora mucho las cosas, pero todavía hay condiciones (if). Podemos ir más allá y aplicar el patrón Estado.


Paso 2: Aplicando el Patrón Estado

Vamos a dividir el comportamiento en clases, una por cada estado, y a usar polimorfismo. Así, según el estado actual, el objeto sabe cómo responder, sin necesidad de estar preguntando con ifs.

Estructura general

Nuestro objeto principal ya no tomará decisiones, sino que delegará en el "estado" actual:

class MobileScreen:
    def __init__(self):
        self.states = {
            'power_off': PowerOffState,
            'screen_disabled': ScreenOffState,
            'screen_on': ScreenOnState,
        }
        self.state = self.states['power_off'](self)

    def power_on(self):
        self.state = self.states['screen_disabled'](self)

    def touch(self):
        self.state.touch()

    def swipe(self):
        self.state.swipe()

    def notify(self, event):
        print(f'Notificando evento: {event}')

Cada clase de estado se hace cargo de los comportamientos posibles: touch() y swipe().


Clases de Estado

Ahora vamos a crear una clase para cada estado.

🔴 Estado: Teléfono Apagado

class PowerOffState:
    def __init__(self, screen):
        self.screen = screen

    def touch(self):
        # Nada pasa si el teléfono está apagado
        pass

    def swipe(self):
        # Tampoco pasa nada
        pass

📴 Estado: Pantalla Apagada

class ScreenOffState:
    def __init__(self, screen):
        self.screen = screen

    def touch(self):
        # Encendemos la pantalla
        self.screen.state = self.screen.states['screen_on'](self.screen)
        self.screen.notify('touch')

    def swipe(self):
        # Nada pasa si solo pasamos el dedo con la pantalla apagada
        pass

🟢 Estado: Pantalla Encendida

class ScreenOnState:
    def __init__(self, screen):
        self.screen = screen

    def touch(self):
        # Notificamos que hubo un toque
        self.screen.notify('touch')

    def swipe(self):
        # Notificamos que hubo un gesto
        self.screen.notify('swipe')

Listo. El comportamiento ya está completamente separado por estados, y el código del objeto principal está limpio y claro. Si más adelante agregamos nuevos estados o eventos, solo tenemos que tocar las clases correspondientes.


Ventajas de este enfoque

✅ Mucho menos if y else complicados.

✅ Es fácil ver qué hace cada "estado".

✅ Agregar comportamientos nuevos es más sencillo.

✅ Separa responsabilidades correctamente.



Resumen

  • El patrón Estado permite manejar cambios de comportamiento según el estado del objeto, sin depender de condicionales.
  • En vez de usar if y variables booleanas, definimos una sola variable con el estado actual.
  • Creamos una clase para cada estado, con su propio comportamiento para cada evento.
  • Gracias al polimorfismo, el objeto principal solo delega la ejecución sin preocuparse de en qué estado está.
  • Este patrón mejora la claridad del código y facilita su mantenimiento y evolución.

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