J'ai une classe en calculant le revenu annuel net des travailleurs. Il a une constante représentant un pourcentage d'impôt. Mais un jour, le taux d'imposition a changé, j'ai donc besoin de corriger le code.
L'acte de fixer cette constante indique-t-il une violation du principe ouvert , puisqu'il postule qu'une classe doit être fermée à la modification?
L'OCP peut être mieux compris lors de la pensée de classes ou de composants fournis par un fournisseur A dans une sorte de bibliothèque de boîtes noire, pour l'utilisation par les utilisateurs B, C et D (note que ceci est juste un modèle mental que j'utilise pour plus de clarté, Peu importe si dans la réalité, le seul utilisateur de la classe est un lui-même).
Si B, C et D peut utiliser ou réutiliser les classes fournies pour différents cas d'utilisation, sans que la nécessité de modifier le code source de la bibliothèque, le composant remplit l'OCP ( en ce qui concerne une catégorie de cas d'utilisation). Il y a différents moyens pour y parvenir, comme
rendre la classe héritée (généralement en conjonction avec le modèle de méthode de modèle ou le modèle de stratégie)
en fournissant des "points d'injection" pour l'injection de dépendance
en fournissant des paramètres de configuration pour la classe ou le composant (par exemple, en ayant un paramètre de constructeur "pourcentage de taxe", comme dans votre cas ou en utilisant un autre mécanisme de configuration)
peut-être d'autres moyens, en fonction du langage de programmation ou de l'écosystème
Les exemples typiques que vous trouvez dans des livres de texte sont souvent du premier ou de second type (je suppose parce que dans les yeux de ces auteurs du livre, le troisième type est trop trivial pour être mentionné).
Comme vous le voyez, cela n'a rien à voir avec interditer aucune modification du code source par le fournisseur A (comme pour la fixation de bugs, l'optimisation ou l'ajout de nouvelles fonctionnalités de manière compatible à l'envers), c'est-à-dire tout à fait sans rapport avec l'OCP. L'OCP concerne la manière dont une conception de l'interface et de la granularité des composants dans la LIB, des scénarios de réveil de manière différents (tels que la résolution de taux d'imposition différents) ne provoquent pas automatiquement des exigences de changement.
Donc, malgré ce que les autres vous ont dit ici, la réponse est clairement "Oui", ce serait une violation de l'OCP.
Edit: semble entre quelqu'un a écrit un article de blog détaillé sur exactement ce sujet. Bien que des parties de cela auraient pu être mieux libellées (comme l'a souligné Derek Elkins), il semble que l'auteur partage généralement mon point de vue que "l'exécution de l'OCP" n'est pas une propriété absolue, mais une chose qui ne peut être évaluée que dans le contexte de certains Catégories de changements d'exigence.
Comme d'autres disent, idéalement, la classe de revenus des travailleurs permettrait de paramétrer la constante, rendant cette classe indépendante de cette valeur.
En fin de compte, la demande d'appel peut également permettre le paramétrage en termes de configuration externe (par exemple un fichier). Une fois que nous avons une configuration externe, nous pouvons modifier le taux d'imposition - bien que vous considérez que si le fichier de configuration est lu qu'une seule fois au démarrage, l'application devra être redémarrée pour les pourcentages de revenus mis à jour pour prendre effet. C'est donc quelque chose à garder dans dérange. Nous pourrions fournir une fonctionnalité d'application pour relire la configuration lorsqu'il est dirigé de le faire, sinon nous pourrions fournir un mécanisme plus compliqué qui noticule lorsque le fichier de configuration change ...
À long terme, vous constaterez peut-être que les problèmes fiscaux nécessitent plus qu'un pourcentage - par exemple, qu'un jour, les lois fiscales sont plus complexes et nécessitent plusieurs pourcentages et certaines constantes (par exemple, le montant inférieur à 10 000 $ taxé à X%, tandis que la reste taxé à Y%).
Cela suggère essentiellement d'utiliser un modèle de stratégie, où la classe principale en question accepte ici un objet de stratégie pour calculer la taxe.
Les différentes stratégies (et% de constantes de $ et $) doivent être choisissiez-la dans le fichier de configuration, et l'ajout d'une nouvelle stratégie nécessite d'ajouter un nouveau code, mais pas nécessairement une mise à jour du code existant.
Chaque stratégie pourrait savoir comment analyser/interpréter ses propres arguments de configuration externes, ainsi que comment calculer la taxe réelle.
Dynamiquement, la taxe peut en outre dépendre de la région des gouverneurs. Vous pourriez avoir des locaux associés à des gains ou avec des employés (ou les deux). Dans la configuration externe, nous pourrions associer des paramètres régionaux avec stratégie fiscale.
Voir également injection de dépendance , où nous gérons ces choses explicitement.
Si vous devez modifier la classe pour modifier la valeur fiscale, sa conception enfreignons effectivement OCP. La conception appropriée, pour ce que vous avez décrit jusqu'à présent, est que la classe de calculatrice prend la valeur de l'impôt en tant que paramètre.
Si votre classe est instanciée (ce qui signifie que ce n'est pas une classe statique), en effectuant la propriété de classe de variable fiscale, dont la valeur est injectée via le constructeur, vous améliorez également la cohésion de la classe.
En bref, votre conception actuelle rend votre classe dépend de une valeur constante qui n'est pas vraiment une constante (définition constante comme valeur qui ne changera jamais, peu importe quoi, comme la valeur de PI). Il viole OCP. Changez la conception pour recevoir la valeur de taxe comme argument du constructeur.
Totalement d'accord avec @becuzz, et je veux juste résumer cela: OCP consiste à trouver des abstractions réutilisées (d'où utiles) injectées dans une classe. Donc, le comportement de la classe est modifié non pas en changeant son code, mais en leur fournissant différentes implémentations. Ceci est fait cristal clair dans le livre de Robert Martin " Développement logiciel agile, principes, modèles et pratiques ", vérifiez le chapitre correspondant "Le principe ouvert fermé" "," L'abstraction est la clé "Sous-Chapitre" . Il clarifie une autre idée fausse que le comportement ne peut être modifié qu'avec héritage. C'était Bertrand Meyer qui a proposé qu'en 1988 dans son livre " Construction logicielle orientée objet ", pas Robert Martin.