Supposons que je reçois la doctrine suivante 2 entité: L'utilisateur peut avoir plusieurs statuts, par exemple: en attente, actif, suspendu. Ces statuts sont nécessaires tout au long du code (services, référentiels, etc.) et également dans la couche d'interface utilisateur (un formulaire d'édition d'utilisateur les afficherait dans une liste déroulante). P> Afin d'éviter de les définir dans plusieurs endroits, ce que j'ai fait jusqu'à présent, c'était d'utiliser une classe pour les maintenir toutes (toutes les constantes de l'application), et il semble un peu comme ceci: P > // example of retrieval by constant name ... it would return an integer
$pendingStatus = App_Constants::getConstantByName( 'USERS.STATUS.PENDING' );
// example of retrieval for UI display purposes ... would return an array
$statuses = App_Constants::getConstantValues('users', 'status');
3 Réponses :
Je pense que vous pouvez le faire de cette façon: sur la couche d'interface utilisateur, vous pouvez obtenir des versions de texte de vos statuts à l'aide d'un service de localisation (si les constantes d'état sont des chiffres, la couche d'utilisateur peut Convertissez-les en chaînes en ajoutant un préfixe, par exemple user_status_0). Dans Symfony2 vues Vous pouvez utiliser un filtre de brindille Si votre site web est juste dans Une langue, alors juste utilisateur :: Statut_xxx fera bien, je pense. Je ne pense pas que vous devriez surcharger la question en créant une nouvelle classe pour tenir des statuts de l'utilisateur. P> Si vous finirez par avoir de nombreux statuts ou d'autres choses liées, je pense que vous devrez créer une entité séparée pour eux. p> p> trans code> pour obtenir la version texte de l'état de l'utilisateur à partir de
Utilisateur code> Domaine de localisation. P>
J'ai finalement fini par faire de cette façon dans quelles constantes de domaine sont concernées, car il semble plus naturel dans une approche DDD. Je continue à utiliser la classe Constantes pour d'autres constantes de grande valeur qui ne sont pas liées au domaine.
Vous pouvez définir votre classe comme dans l'exemple suivant
ContactResource::getTypeList()
Comment est-ce différent de la réponse de Vladislav?
La réponse de Vladislav a raison, mais il est important de définir la méthode de tostring ainsi que de getters et de setters pour l'utiliser. Je veux seulement compléter la réponse :)
Je ne suis pas suivi quand c'est $ Type défini? Alors, comment obtenez-vous le type de ressources associé à votre valeur constante? Merci.
Plusieurs années plus tard et une autre expérience, ce que je considère comme la bonne réponse a changé. La question initiale concerne les constantes de domaine utilisés dans la couche d'interface utilisateur, mais l'exemple donné et les discussions se réfèrent en fait aux concepts suivants: Enums, cartes d'énumjet et objets de valeur. Je n'ai pas eu ces concepts à ce moment-là et les réponses à ma question ne leur ont pas fourni.
Lorsque vous voyez ou pensez de constantes telles que Il est facile de le transformer en un objet de valeur si vous devez ajouter une fonctionnalité à celui-ci (je recommande de le faire par la composition, pas l'héritage) . Revenant à l'entité code> code>, à l'aide de l'Enum ci-dessus, l'entité se retrouverait comme suit: p> remarque le type de colonne est "user_status". Pour que cela fonctionne, vous devez définir un type de doctrine personnalisé et l'enregistrer avec la doctrine. Un tel type ressemblerait à ceci: p> Enfin, lorsqu'il s'agit de satisfaire les besoins de l'interface utilisateur, vous pouvez finir par utiliser des cartes ENUM. N'oubliez pas que l'interface utilisateur pourrait avoir besoin de fonctionnalités supplémentaires telles que la prise en charge de plusieurs langues, de sorte que vous ne pouvez donc pas modifier de telles préoccupations dans le domaine, d'où la séparation: p> Vous pouvez simplement ajouter autant de clés Vous voulez à côté de "nom". Dans l'interface utilisateur, vous pouvez utiliser une telle carte comme celle-ci: p> la fonction résumer: p> Status_Pending code>,
Status_Active code>,
Statut_Suspendue Code> Vous devez penser à une énumération. La standard PHP Enum est insuffisante, j'aime donc utiliser une bibliothèque tierce partie comme Marc-mabe / php- Enum . Voici comment cela ressemblerait à: p>
toarray code> n'est pas disponible dans Mabeenum \ Enumma, mais vous pouvez faire votre propre: p>
Cela fait plus de deux ans, vous êtes toujours d'accord avec tout dans votre réponse?
Oui, je ne changerais rien dans ma réponse.
Votre point de vue est le seul endroit qui a besoin des noms. La couche d'interface utilisateur doit faire toute la conversion entre les noms et les valeurs; Partout ailleurs devrait simplement utiliser la valeur entière. Il peut être utile d'ajouter des méthodes à votre entité comme
Ispending () code>
@rojoca - Lorsque vous dites "Utilisez la valeur entière", vous ne voulez sûrement pas dire quelque chose comme:
si ($ utilisateur-> getstatus () == 2) ... code>. L'interface utilisateur pourrait ne pas être la seule autre couche utilisant ces constantes. Qu'en est-il de ces constantes utilisées dans les requêtes qui ne traversent pas le modèle de domaine (lors de l'utilisation d'une sorte de CQS)?
Non; Dans votre exemple, je pense que
si ($ utilisateur-> ispendant ()) code> est meilleur parce qu'il dit exactement ce que cela signifie. Vous pouvez créer des constantes comme
user :: statut_pending code> dans votre modèle de domaine, puis utilisez-les dans
app_constants code> par exemple, par exemple,
user :: statut_pend => "en attente" code> . App_Constants dépend de votre domaine, que vous ne connaissez pas les valeurs (comme vous le faites actuellement) ou utilisez des constantes de classe; Vous pourriez aussi bien utiliser des constantes.
@rojoca Merci pour les suggestions. J'ai examiné la mise en œuvre d'un type personnalisé (quelque chose comme une énorme), mais comme des types sont des piles de vols et ne tiennent pas l'état, j'aurais besoin d'un nouveau type personnalisé pour chacun de ces champs. En fin de compte sans véritables objets de valeur supportés par la doctrine, je devrai la mettre en œuvre comme vous l'avez suggéré.