SOLIDPrincipios

Abierto/cerrado (OCP)

Las entidades de software deben estar abiertas a extensión, pero cerradas a modificación.

¿Qué es?

El Open/Closed Principle dice que debería poder agregar comportamiento nuevo a un sistema sin modificar código que ya funciona. En la práctica, esto se logra apoyándose en abstracciones (interfaces, polimorfismo) en vez de en condicionales que revisan tipos concretos.

Antes: hay que editar la clase por cada caso nuevo

type ShapeType = 'circle' | 'square';

interface Shape {
  type: ShapeType;
  radius?: number;
  side?: number;
}

class AreaCalculator {
  calculate(shape: Shape): number {
    if (shape.type === 'circle') {
      return Math.PI * shape.radius! ** 2;
    } else if (shape.type === 'square') {
      return shape.side! ** 2;
    }
    // Cada figura nueva obliga a tocar este método
    throw new Error('Figura no soportada');
  }
}

Cada vez que aparece una figura nueva (triángulo, rectángulo...) hay que volver a abrir AreaCalculator y agregar otro else if, con el riesgo de romper los casos que ya funcionaban.

Después: extensión mediante polimorfismo

interface Shape {
  area(): number;
}

class Circle implements Shape {
  constructor(private radius: number) {}

  area(): number {
    return Math.PI * this.radius ** 2;
  }
}

class Square implements Shape {
  constructor(private side: number) {}

  area(): number {
    return this.side ** 2;
  }
}

// Figura nueva: se agrega una clase, no se toca ninguna existente
class Triangle implements Shape {
  constructor(private base: number, private height: number) {}

  area(): number {
    return (this.base * this.height) / 2;
  }
}

class AreaCalculator {
  calculateTotal(shapes: Shape[]): number {
    return shapes.reduce((total, shape) => total + shape.area(), 0);
  }
}

AreaCalculator ya no conoce los tipos concretos: solo depende de la abstracción Shape. Agregar Triangle no requiere tocar ni una línea de las clases existentes.

A tener en cuenta: OCP no prohíbe modificar código nunca; prohíbe que agregar un caso nuevo obligue a reabrir y arriesgar código que ya está probado y funcionando en producción.
polimorfismoabstracciónOCP