Al estudiar patrones de diseño, hay un punto en el que casi inevitablemente nos atascamos.
Son los patrones Strategy y State.
Si colocas lado a lado los diagramas UML (Unified Modeling Language, lenguaje unificado de modelado), parecen prácticamente copiados y pegados. Hay una interfaz, varias implementaciones y un contexto que las contiene.
Es normal pensar: «¿No son simplemente nombres distintos?»
Empecemos por la conclusión. Lo que diferencia ambos patrones no es la estructura, sino la intención. Strategy cambia el algoritmo desde fuera; State hace que el estado avance por sí mismo al siguiente estado desde dentro.
Si te quedas con esta frase mientras lees, no volverás a confundirlos.
La implementación que elimina las condiciones reales mediante objetos de estado continúa paso a paso en Refactorización del patrón State en Swift.
¿Por qué sus estructuras son tan iguales?
Ambos son patrones de comportamiento del libro de patrones de diseño de GoF (Gang of Four).
Ambos usan los mismos elementos: una interfaz común, varias clases que la implementan y un contexto que las contiene.
Por eso resulta realmente difícil distinguirlos solo por el código.
Así se ve el patrón Strategy en código.
protocol PaymentStrategy {
func pay(_ amount: Int)
}
struct CardPayment: PaymentStrategy {
func pay(_ amount: Int) { print("Pago de \(amount) won con tarjeta") }
}
struct KakaoPay: PaymentStrategy {
func pay(_ amount: Int) { print("Pago de \(amount) won con Kakao Pay") }
}
final class Checkout {
var strategy: PaymentStrategy
init(strategy: PaymentStrategy) { self.strategy = strategy }
func pay(_ amount: Int) { strategy.pay(amount) }
}
let checkout = Checkout(strategy: CardPayment())
checkout.pay(10000)
checkout.strategy = KakaoPay() // Se cambia desde fuera
checkout.pay(5000)
// Salida:
// Pago de 10000 won con tarjeta
// Pago de 5000 won con Kakao Pay
Lo importante aquí es quién cambia la strategy: el código cliente externo.
Quien cambió el método de pago de tarjeta a Kakao Pay fue el desarrollador, es decir, alguien externo.
La propia Strategy no sabe en absoluto qué viene después. Tampoco le importa.
Entonces, ¿qué diferencia al patrón State?
En el patrón State, los propios estados deciden las transiciones.
Piensa en un semáforo. La luz roja sabe que después viene la verde, y la verde sabe que después viene la amarilla.
Es decir, cada estado contiene la regla para pasar al siguiente.
protocol TrafficState {
func next(_ light: TrafficLight)
}
final class Red: TrafficState {
func next(_ light: TrafficLight) {
print("Rojo → verde")
light.state = Green() // El estado especifica por sí mismo el siguiente
}
}
final class Green: TrafficState {
func next(_ light: TrafficLight) {
print("Verde → amarillo")
light.state = Yellow()
}
}
final class Yellow: TrafficState {
func next(_ light: TrafficLight) {
print("Amarillo → rojo")
light.state = Red()
}
}
final class TrafficLight {
var state: TrafficState = Red()
func change() { state.next(self) }
}
let light = TrafficLight()
light.change()
light.change()
light.change()
// Salida:
// Rojo → verde
// Verde → amarillo
// Amarillo → rojo
¿Se ve la diferencia?
En Strategy, lo cambiamos directamente desde fuera, como en checkout.strategy = KakaoPay().
En State, light.state = Green() lo realiza la propia clase de estado. El cliente solo llama a change().
Ese es precisamente el punto clave.
Strategy se cambia desde fuera; State avanza por sí mismo desde dentro.
La diferencia decisiva, resumida en tres puntos
Explicarlo solo con palabras puede volver a confundir, así que lo resumimos en una tabla.
| Categoría | Patrón Strategy | Patrón State |
|---|---|---|
| Intención | Sustituir el algoritmo | Cambiar el comportamiento según el estado |
| Quién realiza la transición | Cliente externo | El propio objeto de estado |
| Relación entre objetos | No se conocen (independientes) | Se conocen y se referencian |
| Ciclo de vida | Normalmente se mantiene tras elegirlo | Cambia continuamente durante la ejecución |
Recuerda especialmente la segunda y la tercera fila.
Las strategies no conocen la existencia de las demás. Un pago con tarjeta no necesita conocer Kakao Pay.
En cambio, los estados deben conocerse entre sí. La luz roja crea y entrega directamente el objeto de luz verde.
Saber si «se conocen o no» es la pista más clara para distinguir ambos patrones en el código.
¿Cuándo conviene usarlos y cuándo evitarlos?
Estos son mis criterios para decidirlo en la práctica.
| Situación | Decisión |
|---|---|
| Cuando solo hay varias formas de hacer lo mismo (ordenación, pagos, compresión) | Patrón Strategy |
| Cuando un objeto se comporta de forma distinta según la situación y esta cambia | Patrón State |
| Cuando las reglas de transición forman un bloque complejo de if-else | Resolver con State |
| Cuando es tan sencillo como pasar una sola función | Ambos son excesivos; usa un closure |
También hay que tener en cuenta lo siguiente.
Si solo hay 2 o 3 estados y las transiciones son simples, a menudo basta con enum y switch sin introducir un patrón.
Los patrones son herramientas para controlar la complejidad, no adornos para dar formalidad al código sencillo.
En una entrevista pueden preguntarlo así
P. Los patrones Strategy y State tienen la misma estructura. ¿Cómo se distinguen?
La estructura es casi igual, pero la intención es distinta. Strategy busca sustituir un algoritmo desde fuera, mientras que State busca cambiar el comportamiento según el estado interno. La diferencia decisiva es quién realiza la transición: el cliente en Strategy y el propio objeto de estado en State.
P. En State, los estados se referencian entre sí. ¿No es un problema?
Es cierto que aparece acoplamiento entre estados. Para reducirlo, puedes sacar la lógica de transición de los estados y llevarla al contexto o a una tabla de transiciones independiente. Si aumentan los estados y las transiciones se entrelazan, otra opción es usar una biblioteca de máquinas de estados.
No te intimides aunque los diagramas parezcan idénticos. Pregunta simplemente «¿Quién realiza la transición?» y la respuesta aparecerá enseguida.
Si se cambia desde fuera, es Strategy; si avanza por sí mismo desde dentro, es State. Con recordar esta frase, el artículo de hoy habrá cumplido su objetivo. Volveré con otro patrón que suele confundirse.

