OCP — Principios, apertura para extensión y cierre para modificación

Autor: IT Sectr Publicado: 2026-05-11 Tiempo de lectura: 9 min

OCP (Open/Closed Principle) es el segundo principio de SOLID, que establece: las entidades de software deben estar abiertas para extensión pero cerradas para modificación. Este principio, formulado por Bertrand Meyer en 1988, permite añadir nueva funcionalidad sin cambiar el código existente. Según el libro de Robert Martin Clean Architecture (2017), el principio de apertura se implementa mediante abstracciones y polimorfismo, minimizando el riesgo de errores de regresión.

Puntos Clave

  • OCP — el principio de apertura para extensión y cierre para modificación
  • Extensión se implementa mediante abstracciones, interfaces y polimorfismo
  • Modificación del código existente está prohibida — la nueva funcionalidad se añade sin alterar clases antiguas
  • Polimorfismo — el mecanismo clave de OCP en lenguajes orientados a objetos
  • Violar OCP provoca cambios en cascada al añadir nuevos requisitos

¿Qué es OCP (Open/Closed Principle)?

OCP (Open/Closed Principle) — el principio de apertura para extensión y cierre para modificación. Las clases, módulos y funciones deben diseñarse para que se pueda añadir nuevo comportamiento sin cambiar su código fuente. La extensión se logra mediante herencia, composición o sustitución de implementaciones de interfaces.

Bertrand Meyer en su libro Object-Oriented Software Construction (1988) describió por primera vez OCP mediante herencia: la clase base permanece sin cambios, mientras que las subclases extienden su comportamiento. La interpretación moderna de OCP, propuesta por Robert Martin, se basa en polimorfismo e interfaces: en lugar de herencia, se utilizan contratos abstractos.

La diferencia entre enfoques es significativa. La herencia crea un acoplamiento fuerte entre clases base y derivadas. Las interfaces y la composición proporcionan flexibilidad: la implementación se puede cambiar sin modificar el código cliente. OCP moderno trata sobre abstracción, no sobre herencia.

El polimorfismo como base de OCP

OCP polimórfico utiliza clases abstractas o interfaces para definir un contrato. El código cliente trabaja con la abstracción sin conocer la implementación concreta. La nueva funcionalidad se añade creando una nueva clase que implementa la misma interfaz — sin cambiar ni una línea del código existente. Esto hace que el sistema sea resistente al cambio y predecible para la extensión.

En el desarrollo móvil, este enfoque es omnipresente: el patrón Strategy permite intercambiar algoritmos (compresión de imágenes, almacenamiento en caché, autenticación) a través de una interfaz única. Añadir una nueva estrategia no requiere cambiar el código que la utiliza.

Cómo implementar el principio de apertura y cierre

Implementar OCP comienza aislando el comportamiento variable en una abstracción. Si hay una construcción switch o una cadena if-else que verifica el tipo de un objeto en el código — es una señal para aplicar OCP. Cada rama condicional potencialmente requiere añadir una nueva rama al extender.

El proceso de refactorización bajo OCP incluye tres pasos: identificar el aspecto variable (lo que puede extenderse), aislarlo en una interfaz o clase abstracta, reescribir el código cliente para trabajar con la abstracción en lugar de la clase concreta. Después de esto, la nueva funcionalidad se añade sin cambiar el cliente.

Una aclaración importante: cierre para modificación no es absoluto. Si un cambio de requisito afecta a la propia abstracción o al contrato — el cambio es inevitable. OCP protege contra cambios en las implementaciones, no en los contratos. Un buen diseño asume que los contratos son estables y las implementaciones son variables.

Al evaluar la compatibilidad OCP de una arquitectura, es útil observar los puntos de extensión. Cada punto donde un desarrollador añade if-else o switch para un nuevo tipo es candidato para abstracción. Un sistema diseñado según OCP tiene puntos de extensión predecibles: interfaces con documentación que dice "implementa esta interfaz para añadir un nuevo tipo". En Android, un ejemplo claro es el patrón Factory junto con ViewModelProvider.Factory — añadir un nuevo tipo de ViewModel no requiere cambiar las fábricas existentes.

Estrategias y patrones para OCP

Los patrones más efectivos para cumplir con OCP en el desarrollo móvil incluyen Strategy, Template Method, Decorator y Factory. Cada uno resuelve el problema de extender el comportamiento sin modificar el código existente a través de diferentes mecanismos de diseño orientado a objetos.

Strategy permite intercambiar algoritmos sobre la marcha mediante una interfaz común. En desarrollo iOS, las estrategias se utilizan para animaciones y validación de formularios. Template Method define el esqueleto de un algoritmo en una clase base, y las subclases sobreescriben los pasos — adecuado para pantallas con estructura común pero contenido diferente.

Decorator añade dinámicamente comportamiento a un objeto sin cambiar su clase. En Android, Decorator se usa para envolver un Repository con una capa de caché o registro. Factory Method crea objetos a través de una interfaz, permitiendo que las subclases decidan qué clase instanciar — la base de la creación de dependencias compatible con OCP.

Selección de estrategia para un proyecto móvil

La selección del patrón depende de la estabilidad del comportamiento que se extiende. Strategy es óptima cuando los algoritmos se reemplazan por completo. Template Method — cuando la estructura es fija pero los pasos varían. Decorator — cuando la extensión debe ser transparente para el cliente. Para la mayoría de escenarios en Android e iOS, Strategy + inyección de dependencias es suficiente.

Aplicar estos patrones sin OCP es técnicamente posible pero pierde sentido. Es OCP quien justifica por qué introducimos un nivel adicional de abstracción: para que el sistema pueda crecer sin reescribir el código existente.

Ejemplos de OCP en aplicaciones móviles

Consideremos un ejemplo en Android con procesamiento de pagos. Sin OCP, cada nuevo sistema de pago requiere cambios en la clase manejadora. Con OCP, se añade una nueva implementación de la interfaz sin modificar el código existente.

kotlin
// Violación de OCP: switch requiere modificación al añadir un nuevo sistema
class BadPaymentProcessor {
    fun process(type: String) {
        when (type) {
            "card" -> // procesamiento de tarjeta
            "paypal" -> // procesamiento de PayPal
        }
    }
}

// Diseño compatible con OCP
interface PaymentMethod {
    fun pay(amount: Double)
}

class CardPayment : PaymentMethod {
    override fun pay(amount: Double) { }
}

class PayPalPayment : PaymentMethod {
    override fun pay(amount: Double) { }
}

// Nuevo sistema — nueva clase, sin cambiar el código existente
class ApplePayPayment : PaymentMethod {
    override fun pay(amount: Double) { }
}

Un ejemplo en iOS con validación de campos de texto demuestra la misma lógica a través de protocolos de Swift:

swift
// Validación compatible con OCP
protocol ValidationRule {
    func validate(_ input: String) -> Bool
}

struct EmailRule: ValidationRule {
    func validate(_ input: String) -> Bool {
        return input.contains("@")
    }
}

struct PhoneRule: ValidationRule {
    func validate(_ input: String) -> Bool {
        return input.count == 11
    }
}

// Añadir una nueva regla no requiere cambiar el código del validador
struct PasswordRule: ValidationRule {
    func validate(_ input: String) -> Bool {
        return input.count >= 8
    }
}

La ventaja clave de OCP en estos ejemplos: añadir ApplePay o PasswordRule no requiere modificar las clases existentes. El código se expande horizontalmente — mediante nuevos archivos, no alterando los antiguos. Esto reduce el riesgo de regresión y acelera la implementación de nueva funcionalidad.

Errores típicos al violar OCP

La violación más común es una construcción switch o when basada en el tipo de objeto. Cada vez que se añade un nuevo tipo, hay que encontrar todos esos switch en el código y añadir una nueva rama. Un switch omitido es un error en tiempo de ejecución difícil de detectar en tiempo de compilación.

En el desarrollo móvil, OCP se viola al usar clases enum gigantes con métodos que dependen del valor del enum. Añadir un nuevo elemento enum requiere cambiar cada switch en todo el proyecto. La alternativa es el polimorfismo a través de una interfaz, donde cada tipo implementa su propio comportamiento.

Otra violación típica es el God Adapter: RecyclerView.Adapter (Android) o UITableViewDataSource (iOS) que maneja diferentes tipos de celdas mediante if-else. Cada nuevo tipo de celda requiere extender el adaptador. La solución es un ViewHolder polimórfico con un método bind común, donde cada tipo de celda es responsable de su propia representación.

Cómo evitar violar OCP

Medidas preventivas incluyen: evitar switch basado en tipo en favor del polimorfismo, inyectar dependencias a través de interfaces y usar el patrón Factory para crear objetos según configuración. Analizar el código en busca de "conmutadores por tipo" es una parte obligatoria de la revisión de código en equipos orientados a OCP.

Refactorizar una violación existente de OCP se realiza mediante Replace Conditional with Polymorphism: cada rama condicional se convierte en una clase separada que implementa una interfaz común. El código cliente se reescribe para trabajar con la interfaz, y la implementación concreta se suministra a través de una fábrica o contenedor DI.

Es importante entender que OCP y el polimorfismo no resuelven todos los problemas de extensión. Si la arquitectura se elige incorrectamente, añadir nueva funcionalidad requerirá cambiar no solo las implementaciones sino también los contratos. Una buena arquitectura predice las direcciones de extensión y coloca abstracciones exactamente en esos puntos. Las inversiones en OCP rinden más cuanto más tiempo vive el proyecto y más a menudo cambian los requisitos de módulos específicos.

Preguntas Frecuentes

¿Significa OCP que el código no se puede cambiar en absoluto?

No. OCP prohíbe cambiar el código existente al añadir nueva funcionalidad relacionada con la misma abstracción. Cambiar un contrato, corregir errores y refactorizar no son violaciones de OCP — el principio protege contra cambios en cascada durante la extensión.

¿Cómo se relaciona OCP con el patrón Strategy?

Strategy es una implementación directa de OCP. La interfaz de estrategia define el contrato, el cliente depende de la abstracción y las estrategias concretas implementan el comportamiento variable. Añadir una nueva estrategia no requiere cambiar el cliente — esto es apertura para extensión con cierre para modificación.

¿Se puede cumplir OCP sin interfaces?

Sí, mediante herencia y Template Method: la clase base define el esqueleto del algoritmo y las subclases sobreescriben los pasos. Sin embargo, la herencia crea un acoplamiento fuerte y es menos flexible que las interfaces. En el desarrollo moderno, las interfaces y la composición se consideran la forma preferida de implementar OCP.

¿Cómo afecta OCP a las pruebas?

El código compatible con OCP simplifica las pruebas: cada implementación de interfaz se prueba de forma aislada. El código cliente se prueba con una implementación mock, lo que permite verificar la lógica sin vincularse a un comportamiento específico. Expandir el sistema no requiere reescribir las pruebas existentes.

¿Siempre hay que esforzarse por OCP?

No. OCP está justificado cuando la extensión funcional es predecible. Para código estable que no está planificado extender, la abstracción adicional es excesiva. YAGNI (You Ain't Gonna Need It) es un buen contrapeso a OCP: la abstracción se introduce cuando aparece una segunda variante de comportamiento, no de forma preventiva.

Resumen

  • OCP (Open/Closed Principle) — el principio de apertura para extensión y cierre para modificación
  • Extensión se implementa mediante interfaces, polimorfismo y composición en lugar de herencia
  • Switch por tipo — el antipatrón principal que viola OCP y requiere cambios con cada nuevo tipo
  • Strategy y Template Method — los patrones principales para cumplir OCP en proyectos móviles
  • Polimorfismo reemplaza las construcciones condicionales y hace que el código sea extensible sin modificación
  • Refactorizar una violación de OCP se realiza mediante Replace Conditional with Polymorphism
  • YAGNI limita OCP: la abstracción se introduce cuando aparece una segunda implementación, no anticipadamente

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también