Les interfaces PHP permettent la définition de constantes dans une interface, par exemple
interface FooBar
{
const FOO = 1;
const BAR = 2;
}
echo FooBar::FOO; // 1
Toute classe d'implémentation aura automatiquement ces constantes disponibles, par exemple
class MyFooBar implement FooBar
{
}
echo MyFooBar::FOO; // 1
Ma propre opinion à ce sujet est que tout ce qui est mondial est mauvais . Mais je me demande si la même chose s'applique aux constantes d'interface. Étant donné que le codage par rapport à une interface est considéré comme une bonne pratique en général, l'utilisation des constantes d'interface est-elle les seules constantes acceptables à utiliser en dehors d'un contexte de classe?
Bien que je sois curieux de connaître votre opinion personnelle et de savoir si vous utilisez ou non des constantes d'interface, je recherche principalement des raisons objectives dans vos réponses. Je ne veux pas que ce soit une question de type sondage. Je suis intéressé par l'effet de l'utilisation des constantes d'interface sur la maintenabilité. Couplage. Ou des tests unitaires. Quel est le lien avec SOLID PHP? Viole-t-il des principes de codage considérés comme des bonnes pratiques en PHP? Vous avez eu l'idée …
Remarque: il y a une question similaire pour Java qui énumère de très bonnes raisons pour lesquelles elles sont de mauvaises pratiques, mais comme Java n'est pas PHP, j'ai estimé qu'il était justifié de la poser à nouveau dans la balise PHP.
Réponses:
Eh bien, je pense que cela se résume à la différence entre bien et assez bien .
Alors que dans la plupart des cas, vous pouvez éviter l'utilisation de constantes en implémentant d'autres modèles (stratégie ou peut-être poids mouche), il y a quelque chose à dire pour ne pas avoir besoin d'une demi-douzaine d'autres classes pour représenter un concept. Je pense que cela se résume à la probabilité que d'autres constantes soient nécessaires. En d'autres termes, est-il nécessaire d'étendre l'ENUM fourni par les constantes sur l'interface. Si vous pouvez prévoir le besoin de l'étendre, optez pour un modèle plus formel. Sinon, cela peut suffire (ce sera assez bon, et donc moins de code à écrire et à tester). Voici un exemple d'utilisation assez bonne et mauvaise:
Mauvais:
Assez bien:
Maintenant, la raison pour laquelle j'ai choisi ces exemples est simple. L'
User
interface définit une énumération de types d'utilisateurs. Ceci est très susceptible de s'étendre avec le temps et serait mieux adapté par un autre modèle. MaisHTTPRequest_1_1
c'est un cas d'utilisation décent, puisque l'énumération est définie par RFC2616 et ne changera pas pendant la durée de vie de la classe.En général, je ne vois pas le problème des constantes et des constantes de classe comme un problème global . Je le vois comme un problème de dépendance. C'est une distinction étroite, mais définitive. Je vois les problèmes globaux comme des variables globales qui ne sont pas appliquées et, en tant que telles, créent une dépendance globale douce. Mais une classe codée en dur crée une dépendance imposée et, en tant que telle, crée une dépendance globale dure. Les deux sont donc des dépendances. Mais je considère que le global est bien pire car il n'est pas appliqué ... C'est pourquoi je n'aime pas regrouper les dépendances de classe avec des dépendances globales sous la même bannière ...
Si vous écrivez
MyClass::FOO
, vous êtes codé en dur pour les détails d'implémentation deMyClass
. Cela crée un couplage dur, ce qui rend votre code moins flexible et doit donc être évité. Cependant, des interfaces existent pour permettre exactement ce type de couplage. N'introduitMyInterface::FOO
donc aucun couplage en béton. Cela dit, je n'introduirais pas une interface simplement pour y ajouter une constante.Donc, si vous utilisez des interfaces et que vous êtes très sûr que vous (ou n'importe qui d'autre d'ailleurs) n'aurez pas besoin de valeurs supplémentaires, alors je ne vois pas vraiment de gros problème avec les constantes d'interface ... Le meilleur les conceptions n'incluraient pas de constantes ou de conditions ou de nombres magiques ou de chaînes magiques ou quoi que ce soit codé en dur. Cependant, cela ajoute du temps supplémentaire au développement, car vous devez tenir compte des utilisations. À mon avis, la plupart du temps, il vaut vraiment la peine de prendre le temps supplémentaire de créer un excellent design solide. Mais il y a des moments où assez bien est vraiment acceptable (et il faut un développeur expérimenté pour comprendre la différence), et dans ces cas, tout va bien.
Encore une fois, c'est juste mon point de vue là-dessus ...
la source
Je pense qu'il est généralement préférable de gérer les constantes, des constantes spécialement énumérées, comme un type distinct ("classe") de votre interface:
ou, si vous souhaitez utiliser une classe comme espace de noms:
Ce n'est pas que vous n'utilisez que des constantes, vous utilisez le concept de valeurs énumérées ou d'énumérations, dont un ensemble de valeurs restreintes est considéré comme un type spécifique, avec un usage spécifique ("domaine"?)
la source