J'ai une classe qui calcule le revenu annuel net des travailleurs. Il a une constante représentant un pourcentage de taxe. Mais un jour, le taux d'imposition a changé, je dois donc corriger le code.
Le fait de fixer cette constante indique-t-il une violation du principe ouvert-fermé , car il postule qu'une classe doit être fermée à toute modification?
object-oriented
object-oriented-design
solid
Analyse Paradisys
la source
la source
Réponses:
L'OCP peut être mieux compris en pensant aux classes ou aux composants fournis par un fournisseur A dans une sorte de bibliothèque de boîte noire, pour une utilisation par les utilisateurs B, C et D (notez que ce n'est qu'un modèle mental que j'utilise pour plus de clarté, peu importe si en réalité le seul utilisateur de la classe est A lui-même).
Si B, C et D peuvent utiliser ou réutiliser les classes fournies pour différents cas d'utilisation, sans avoir besoin de modifier le code source de la bibliothèque, alors le composant remplit l'OCP ( par rapport à une catégorie de cas d'utilisation ). Il existe différents moyens pour y parvenir, comme
rendre la classe héritable (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 constructeur "pourcentage de taxe", comme dans votre cas, ou en utilisant un autre mécanisme de configuration)
peut-être d'autres moyens, selon le langage de programmation ou l'écosystème
Les exemples typiques que vous trouvez dans les manuels sont souvent du premier ou du deuxième type (je suppose que, aux yeux des auteurs de ces livres, le troisième type est trop trivial pour être mentionné).
Comme vous le voyez, cela n'a rien à voir avec l'interdiction de tout changement du code source par le fournisseur A (comme pour la correction de bogues, l'optimisation ou l'ajout de nouvelles fonctionnalités d'une manière rétrocompatible), ce qui est tout à fait indépendant de l'OCP. L'OCP concerne la façon dont A conçoit l'interface et la granularité des composants dans la bibliothèque, de sorte que différents scénarios de réutilisation (comme le réajustement avec différents taux de taxe) n'entraînent pas automatiquement des exigences de changement.
Donc malgré ce qu'on vous 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 certaines parties auraient pu être mieux formulées (comme l'a souligné Derek Elkins), il semble que l'auteur partage généralement mon point de vue selon lequel "remplir l'OCP" n'est pas une propriété absolue, mais quelque chose qui ne peut être évalué que dans le contexte de certains catégories de modifications des exigences.
la source
Comme d'autres le disent, l'idéal serait que la classe de revenu des travailleurs permette le paramétrage de la constante, rendant cette classe indépendante de cette valeur.
En fin de compte, l'application appelante pourrait également permettre le paramétrage en termes de configuration externe (par exemple un fichier). Une fois que nous avons une configuration externe, nous pouvons changer le taux de taxe - mais considérez que si le fichier de configuration n'est lu qu'une seule fois au démarrage, l'application devra être redémarrée pour que les pourcentages de taxe mis à jour prennent effet, c'est donc quelque chose à conserver esprit. Nous pourrions fournir une fonctionnalité d'application pour relire la configuration lorsque cela est demandé, ou nous pourrions fournir un mécanisme plus compliqué qui remarque lorsque le fichier de configuration change ...
À long terme, vous constaterez peut-être que les problèmes fiscaux nécessitent plus qu'un simple pourcentage - par exemple, qu'un jour les lois fiscales seront plus complexes et nécessiteront plusieurs pourcentages et certaines constantes (par exemple, le montant inférieur à 10000 $ taxé à X%, tandis que le le reste est taxé à Y%).
Cela suggère essentiellement d'utiliser un modèle de stratégie, où la classe principale en question ici accepte un objet de stratégie pour calculer la taxe.
Les différentes stratégies (et les constantes% et s) doivent être choisies dans le fichier de configuration, et maintenant, l'ajout d'une nouvelle stratégie nécessite l'ajout de nouveau code, mais pas nécessairement des mises à jour du code existant.
Chaque stratégie peut savoir comment analyser / interpréter ses propres arguments de configuration externes, ainsi que la façon de calculer la taxe réelle.
Dynamiquement, la taxe peut en outre dépendre des paramètres régionaux en vigueur, vous pouvez donc avoir des paramètres régionaux associés aux revenus ou aux employés (ou les deux). Dans la configuration externe, nous pouvons associer les paramètres régionaux à la stratégie fiscale.
Voir également l' injection de dépendance , où nous gérons ces choses de manière explicite.
la source
Si vous devez modifier la classe pour changer la valeur de la taxe, sa conception viole en effet l'OCP. La conception appropriée, pour ce que vous avez décrit jusqu'à présent, est que la classe de calculatrice prenne la valeur de taxe comme paramètre.
Si votre classe est instanciée (ce qui signifie que ce n'est pas une classe statique), en créant la propriété de classe de variable fiscale, dont la valeur est injectée via le constructeur, vous amélioreriez également la cohésion de la classe.
En bref, votre conception actuelle fait dépendre votre classe d'une valeur constante qui n'est pas vraiment une constante (définissant la constante comme une valeur qui ne changerait jamais quoi qu'il arrive, comme la valeur de PI). Il viole l'OCP. Modifiez la conception pour recevoir la valeur de taxe comme argument constructeur.
la source
Tout à fait d'accord avec @Becuzz, et je veux juste résumer ceci: OCP consiste à trouver des abstractions réutilisées (donc utiles) qui sont injectées dans une classe. Ainsi, le comportement de la classe est modifié non pas en changeant son code, mais en lui fournissant différentes implémentations. Ceci est parfaitement clair dans le livre de Robert Martin " Développement logiciel agile, principes, modèles et pratiques ", consultez le chapitre correspondant "Le principe ouvert-fermé", le sous-chapitre "L'abstraction est la clé". Il clarifie une autre idée fausse selon laquelle le comportement ne peut être modifié qu'avec l'héritage. C'est Bertrand Meyer qui a proposé cela en 1988 dans son livre « Object Oriented Software Construction », pas Robert Martin.
la source
La façon dont je le vois n'est pas une violation du principe ouvert et fermé. Pourtant, le fait que quelque chose qui est appelé à changer dans le temps (comme le pourcentage de taxe) soit une constante est un défaut de conception: vous ne devez pas modifier la valeur de la constante mais la façon dont vous gérez le pourcentage de taxe. Cela devrait être un type de paramètre qui pourrait être modifié sans recompiler le tout.
la source