En Meyer's Object-Oriented Software Construction (1988) define el principio abierto / cerrado de la siguiente manera:
- Se dirá que un módulo está abierto si todavía está disponible para la extensión. Por ejemplo, debería ser posible agregar campos a las estructuras de datos que contiene, o nuevos elementos al conjunto de funciones que realiza.
- Se dirá que un módulo está cerrado si está disponible para su uso por otros módulos. Esto supone que el módulo ha recibido una descripción estable y bien definida (la interfaz en el sentido de ocultar información).
Él continúa diciendo:
Si vuelve a abrir un módulo, también debe volver a abrir todos sus clientes para actualizarlos, ya que dependen de la versión anterior. ... [Este problema] surge cada vez que un módulo debe extenderse por una nueva función o elemento de datos, lo que desencadena cambios en clientes directos e indirectos. ... Con los enfoques clásicos de diseño y programación, no hay forma de escribir módulos abiertos y cerrados.
La solución de Meyer a este dilema es: nunca amplíe un módulo de biblioteca modificando las clases existentes; en su lugar, escriba un nuevo módulo que subclasifique las clases existentes y haga que los nuevos clientes dependan de ese nuevo módulo.
Ahora, en 1988, estaba escribiendo programas de juguete (de procedimiento) en Turbo Pascal y Blankenship Basic, y mi experiencia profesional del siglo XXI es en JVM, CLR y en lenguajes dinámicos, así que no sé qué quería decir Meyer por "enfoques clásicos de diseño y programación".
El ejemplo concreto de Meyer de por qué los módulos del cliente deben volver a abrirse (una declaración de cambio en una enumeración que ahora tiene más miembros, que requiere más casos) parece bastante razonable, pero no justifica la afirmación de que cada vez que agrega funcionalidad a una biblioteca módulo, necesita actualizar todos sus clientes .
¿Hay alguna razón histórica de que esta afirmación pareciera evidente en 1988? Por ejemplo, ¿agregar funciones o estructuras de datos a una biblioteca estática en C cambió el diseño de tal manera que incluso con API compatibles con versiones anteriores, los clientes tuvieran que volver a compilarse? ¿O Meyer realmente está hablando de un mecanismo para hacer cumplir la compatibilidad con API hacia atrás?