Tengo una clase que calcula el ingreso neto anual de los trabajadores. Tiene una constante que representa un porcentaje de impuestos. Pero un día la tasa de impuestos ha cambiado, así que necesito arreglar el código.
¿El acto de arreglar esta constante indica una violación del Principio Abierto-Cerrado , ya que postula que una clase debería estar cerrada a modificaciones?
object-oriented
object-oriented-design
solid
Análisis Paradisys
fuente
fuente
Respuestas:
El OCP se puede entender mejor cuando se piensa en clases o componentes proporcionados por un proveedor A en algún tipo de biblioteca de recuadro negro, para uso de los usuarios B, C y D (tenga en cuenta que este es solo un modelo mental que estoy usando para mayor claridad, no importa si en realidad el único usuario de la clase es el mismo A).
Si B, C y D pueden usar o reutilizar las clases proporcionadas para diferentes casos de uso, sin la necesidad de modificar el código fuente de la biblioteca, entonces el componente cumple con el OCP ( con respecto a una categoría de casos de uso ). Hay diferentes medios para lograr esto, como
hacer que la clase sea heredable (generalmente junto con el patrón de método de plantilla o el patrón de estrategia)
al proporcionar "puntos de inyección" para la inyección de dependencia
proporcionando parámetros de configuración para la clase o componente (por ejemplo, teniendo un parámetro de constructor "porcentaje de impuestos", como en su caso, o utilizando algún otro mecanismo de configuración)
quizás otros medios, dependiendo del lenguaje de programación o del ecosistema
Los ejemplos típicos que se encuentran en los libros de texto son a menudo del primer o segundo tipo (supongo que, a los ojos de los autores de esos libros, el tercer tipo es demasiado trivial para que valga la pena mencionarlo).
Como puede ver, esto no tiene nada que ver con prohibir cualquier cambio en el código fuente por parte del proveedor A (como la corrección de errores, la optimización o la adición de nuevas funciones de una manera compatible con versiones anteriores), que no está relacionado con el OCP. El OCP se trata de cómo A diseña la interfaz y la granularidad de los componentes en la biblioteca, de modo que los diferentes escenarios de reutilización (como el rescate con diferentes tasas impositivas) no inducen automáticamente requisitos para el cambio.
Entonces, a pesar de lo que otros le dicen aquí, la respuesta es claramente "sí" , sería una violación del OCP.
EDITAR: parece que alguien escribió una publicación de blog detallada sobre este tema. Aunque algunas partes podrían haber sido mejor redactadas (como señaló Derek Elkins), parece que el autor generalmente comparte mi punto de vista de que "cumplir el OCP" no es una propiedad absoluta, sino algo que solo puede evaluarse en el contexto de ciertas categorías de cambios de requisitos.
fuente
Como otros dicen, idealmente la clase de ingresos del trabajador permitiría la parametrización de la constante, haciendo que esta clase sea independiente de ese valor.
En última instancia, la aplicación de llamada también podría permitir la parametrización en términos de configuración externa (por ejemplo, un archivo). Una vez que tengamos la configuración externa, podemos cambiar la tasa de impuestos, aunque tenga en cuenta que si el archivo de configuración se lee solo una vez al inicio, entonces la aplicación tendrá que reiniciarse para que los porcentajes de impuestos actualizados surtan efecto, por lo que es algo a tener en cuenta mente. Podríamos proporcionar una función de aplicación para releer la configuración cuando se nos indique, o podríamos proporcionar un mecanismo más complicado que se da cuenta cuando cambia el archivo de configuración ...
A largo plazo, es posible que los problemas impositivos requieran más que solo un porcentaje; por ejemplo, que un día las leyes impositivas son más complejas y requieren varios porcentajes y algunas constantes (por ejemplo, la cantidad por debajo de $ 10k gravada con X%, mientras que el resto gravado al Y%).
Básicamente, esto sugiere utilizar un patrón de estrategia, donde la clase principal en cuestión aquí acepta un objeto de estrategia para calcular el impuesto.
Las diversas estrategias (y las constantes de% y $) deben poder elegirse desde el archivo de configuración, y ahora, agregar una nueva estrategia requiere agregar algún código nuevo, pero no necesariamente actualizaciones del código existente.
Cada estrategia puede saber cómo analizar / interpretar sus propios argumentos de configuración externa, junto con cómo calcular el impuesto real.
Dinámicamente, el impuesto puede depender aún más de la configuración regional que rige, por lo que puede tener una configuración regional asociada con las ganancias o con los empleados (o ambos). En la configuración externa, podríamos asociar la configuración regional con la estrategia fiscal.
También vea inyección de dependencia , donde gestionamos estas cosas explícitamente.
fuente
Si necesita modificar la clase para cambiar el valor del impuesto, entonces su diseño de hecho está violando el OCP. El diseño apropiado, para lo que ha descrito hasta ahora, es que la clase calculadora tome el valor del impuesto como parámetro.
Si su clase está instanciada (lo que significa que no es una clase estática), al hacer la propiedad de clase de la variable de impuestos, cuyo valor se inyecta a través del constructor, también mejoraría la cohesión de la clase.
En resumen, su diseño actual hace que su clase dependa de un valor constante que no es realmente una constante (definiendo constante como un valor que nunca cambiaría sin importar qué, como el valor de PI). Viola OCP. Cambie el diseño para recibir el valor fiscal como argumento del constructor.
fuente
Totalmente de acuerdo con @Becuzz, y solo quiero resumir esto: OCP se trata de encontrar abstracciones reutilizadas (por lo tanto, útiles) que se inyectan en una clase. Por lo tanto, el comportamiento de la clase se modifica no cambiando su código, sino proporcionándole diferentes implementaciones. Esto se aclara en el libro de Robert Martin " Desarrollo, principios, patrones y prácticas de software ágil ", consulte el capítulo correspondiente "El principio abierto-cerrado", el subcapítulo "La abstracción es la clave". Aclara otro concepto erróneo de que el comportamiento solo puede modificarse con la herencia. Fue Bertrand Meyer quien propuso eso en 1988 en su libro " Construcción de software orientado a objetos ", no Robert Martin.
fuente
A mi modo de ver, no es una violación del principio abierto cerrado. Sin embargo, el hecho de que algo que está destinado a cambiar en el tiempo (como el porcentaje de impuestos) es una constante es una falla de diseño: no debe cambiar el valor de la constante sino cómo maneja el porcentaje de impuestos. Esto debería ser algún tipo de configuración que podría modificarse sin volver a compilar todo.
fuente