
Principio Abierto / Cerrado (Open/Closed Principle)

Victor Arana Flores
13 May 2025

El Principio Abierto/Cerrado, parte esencial de los principios SOLID de la programación orientada a objetos, establece que:
"Las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas para su extensión, pero cerradas para su modificación."
En otras palabras, deberías poder agregar nuevas funcionalidades sin tener que cambiar el código existente. Esto se logra diseñando tus sistemas de manera que puedan ser extendidos mediante herencia, composición o inyección de dependencias.
👉 ¿Quieres aprender más sobre este y otros principios SOLID con ejemplos prácticos en PHP?
Únete a mi curso de Patrones de Diseño con PHP.
¿Por qué es importante el principio abierto/cerrado?
Aplicar este principio correctamente trae beneficios muy concretos en proyectos reales:
1. Evita romper código que ya funciona
Modificar clases existentes para agregar nuevas funcionalidades puede introducir errores no deseados en partes del sistema que ya estaban funcionando. El principio OCP reduce este riesgo al evitar modificaciones directas.
2. Facilita el mantenimiento
Un sistema que se puede extender sin alterar lo que ya existe es más fácil de mantener. Los cambios son localizados y predecibles.
3. Fomenta la reutilización de código
Al trabajar con abstracciones, como interfaces o clases base, puedes reutilizar componentes en distintos contextos sin duplicar lógica.
4. Hace tu software más escalable
Cuando las necesidades del negocio cambian (por ejemplo, se necesita un nuevo tipo de reporte, descuento o notificación), puedes adaptarte rápidamente sin necesidad de revisar cada rincón del código.
Un mal ejemplo: sistema de reportes
Supongamos que tenemos una clase que genera reportes en distintos formatos:
class ReportGenerator {
public function generate($type, $data) {
if ($type === 'pdf') {
// Generar PDF
echo "Generando reporte en PDF...";
} elseif ($type === 'excel') {
// Generar Excel
echo "Generando reporte en Excel...";
} else {
throw new Exception("Tipo de reporte no soportado.");
}
}
}
¿Cuál es el problema?
Cada vez que se necesite agregar un nuevo tipo de reporte (por ejemplo, HTML o CSV), será necesario modificar esta clase, violando el principio abierto/cerrado.
Solución: aplicar el principio correctamente
Podemos solucionar este problema utilizando polimorfismo e interfaces:
interface Report {
public function generate(array $data): void;
}
class PDFReport implements Report {
public function generate(array $data): void {
echo "Generando reporte en PDF...";
}
}
class ExcelReport implements Report {
public function generate(array $data): void {
echo "Generando reporte en Excel...";
}
}
Y el generador de reportes ahora depende de la abstracción:
class ReportGenerator {
private Report $report;
public function __construct(Report $report) {
$this->report = $report;
}
public function generate(array $data): void {
$this->report->generate($data);
}
}
Ahora puedes agregar un HTMLReport
o CSVReport
sin tocar ReportGenerator
.
Otro ejemplo: cálculo de descuentos
Implementación incorrecta:
class DiscountCalculator {
public function calculate($type, $amount) {
if ($type === 'student') {
return $amount * 0.8;
} elseif ($type === 'senior') {
return $amount * 0.7;
}
return $amount;
}
}
Cada nuevo tipo de descuento implica modificar esta clase.
Implementación correcta:
interface DiscountStrategy {
public function apply(float $amount): float;
}
class StudentDiscount implements DiscountStrategy {
public function apply(float $amount): float {
return $amount * 0.8;
}
}
class SeniorDiscount implements DiscountStrategy {
public function apply(float $amount): float {
return $amount * 0.7;
}
}
class DiscountCalculator {
private DiscountStrategy $strategy;
public function __construct(DiscountStrategy $strategy) {
$this->strategy = $strategy;
}
public function calculate(float $amount): float {
return $this->strategy->apply($amount);
}
}
Esta implementación permite extender el sistema con nuevos tipos de descuento sin modificar DiscountCalculator
.
Conclusión
El Principio Abierto/Cerrado no es solo una técnica de programación: es una filosofía de diseño que promueve estabilidad sin rigidez. Nos permite crear sistemas donde el cambio es posible sin miedo, porque está planificado desde el inicio.
En el mundo real, donde los requisitos cambian constantemente, seguir este principio hace una gran diferencia entre un sistema que crece saludablemente y uno que se vuelve inmanejable.
👉 ¿Te gustaría profundizar más en principios SOLID y patrones de diseño con ejemplos aplicables a proyectos reales?
Inscríbete en mi curso de Patrones de Diseño con PHP y lleva tus habilidades al siguiente nivel.
1 comentarios
Inicia sesión para comentar
Comentarios:
-
Mauricio Herrera hace 1 mes
Hola profe, cuando va a sacar un curso de webapps con laravel, me inscribiria de inmediato.