Entiendo la intención del principio abierto-cerrado. Está destinado a reducir el riesgo de romper algo que ya funciona mientras se modifica, al decirle que intente extender sin modificar.
Sin embargo, tuve algunos problemas para entender cómo se aplica este principio en la práctica. A mi entender, hay dos formas de aplicarlo. Antes y después de un posible cambio:
Antes: programe abstracciones y "prediga el futuro" tanto como pueda. Por ejemplo, un método
drive(Car car)tendrá que cambiar siMotorcyclese agregan s al sistema en el futuro, por lo que probablemente viola OCP. Perodrive(MotorVehicle vehicle)es menos probable que el método tenga que cambiar en el futuro, por lo que se adhiere a OCP.Sin embargo, es bastante difícil predecir el futuro y saber de antemano qué cambios se realizarán en el sistema.
Después: cuando se necesita un cambio, extienda una clase en lugar de modificar su código actual.
La práctica # 1 no es difícil de entender. Sin embargo, es la práctica # 2 que tengo problemas para entender cómo presentar una solicitud.
Por ejemplo (la aparté de un video en YouTube): Digamos que tenemos un método en una clase que acepta CreditCardobjetos: makePayment(CraditCard card). Un día Vouchers se agregan al sistema. Este método no los admite, por lo que debe modificarse.
Al implementar el método en primer lugar, no pudimos predecir el futuro y programar en términos más abstractos (por ejemplo makePayment(Payment pay), ahora tenemos que cambiar el código existente.
La práctica # 2 dice que deberíamos agregar la funcionalidad extendiendo en lugar de modificar. Qué significa eso? ¿Debo subclasificar la clase existente en lugar de simplemente cambiar su código existente? ¿Debo hacer algún tipo de envoltura alrededor para evitar reescribir el código?
¿O el principio ni siquiera se refiere a 'cómo modificar / agregar correctamente la funcionalidad', sino que se refiere a 'cómo evitar tener que hacer cambios en primer lugar (es decir, programa para abstracciones)?