Skip to main content

Inicia sesión en CleanKata

Sigue tu progreso, gana XP y desbloquea todas las lecciones.

Al iniciar sesión aceptas nuestros Términos de uso y Política de privacidad.

Arquitectura Limpia60 XP6 min

Los Dos Valores del Software: Comportamiento vs Estructura

El software tiene valor por su comportamiento y su estructura. Un sistema rígido dejará de funcionar cuando los requisitos cambien.

Por qué importa

Cada pieza de software proporciona dos valores a sus partes interesadas: comportamiento (lo que hace ahora mismo) y estructura (su capacidad de cambiar). La mayoría de los desarrolladores y partes interesadas del negocio se enfocan completamente en el comportamiento — si funciona, publícalo. Pero un sistema que funciona hoy y no puede cambiarse mañana ya ha comenzado a morir.

Martin argumenta que la estructura es más importante que el comportamiento. Un sistema que no funciona del todo bien pero es fácil de corregir puede hacerse funcionar. Un sistema que funciona perfectamente pero nunca puede cambiarse se volverá inútil en el momento en que cambien los requisitos — y los requisitos siempre cambian. La responsabilidad del desarrollador es luchar por la estructura que mantiene el sistema blando (soft-ware: fácil de cambiar).

✗El problema

Codificar el comportamiento en una función no deja lugar para el cambio. Cuando la estrategia de precios debe diferir por región, temporada o tipo de cliente, cada cambio requiere tocar — y probar — la misma función.

Bad

class OrderProcessor:
    def calculate_total(self, items: list[dict]) -> float:
        total    = sum(i["price"] * i["qty"] for i in items)
        discount = total * 0.10  # hardcoded — impossible to change
        return total - discount
class OrderProcessor {
  calculateTotal(items: { price: number; qty: number }[]): number {
    const total = items.reduce((s, i) => s + i.price * i.qty, 0);
    return total * 0.90; // hardcoded — rigid, not soft
  }
}

✓La solución

Injecting the strategy keeps behavior correct today and structure flexible for tomorrow. New discount rules are new classes, not edits to existing ones.

Good

class PercentDiscount:
    def __init__(self, rate: float): self.rate = rate
    def apply(self, total: float) -> float:
        return total * (1 - self.rate)

class OrderProcessor:
    def __init__(self, discount):
        self.discount = discount

    def calculate_total(self, items: list[dict]) -> float:
        total = sum(i["price"] * i["qty"] for i in items)
        return self.discount.apply(total)

proc = OrderProcessor(PercentDiscount(0.10))
print(proc.calculate_total([{"price": 100, "qty": 2}]))
interface DiscountStrategy {
  apply(total: number): number;
}

class PercentDiscount implements DiscountStrategy {
  constructor(private rate: number) {}
  apply(total: number) { return total * (1 - this.rate); }
}

class OrderProcessor {
  constructor(private discount: DiscountStrategy) {}
  calculateTotal(items: { price: number; qty: number }[]): number {
    const total = items.reduce((s, i) => s + i.price * i.qty, 0);
    return this.discount.apply(total);
  }
}

💡Conclusión clave

El comportamiento satisface los requisitos de hoy. La estructura es lo que te permite satisfacer los de mañana — y es la cosa más difícil y valiosa de proteger.

🔧 Algunos ejercicios pueden tener errores. Si algo parece incorrecto, usa el botón Feedback (abajo a la derecha) para reportarlo — nos ayuda a corregirlo rápido.

Pista: El comportamiento satisface los requisitos de hoy. La estructura permite satisfacer los de mañana.

✗ Tu versión