9
votes

Constantes en doctrine 2 entités

Supposons que je reçois la doctrine suivante 2 entité: xxx pré>

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');


4 commentaires

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 ()


@rojoca - Lorsque vous dites "Utilisez la valeur entière", vous ne voulez sûrement pas dire quelque chose comme: si ($ utilisateur-> getstatus () == 2) ... . 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 ()) est meilleur parce qu'il dit exactement ce que cela signifie. Vous pouvez créer des constantes comme user :: statut_pending dans votre modèle de domaine, puis utilisez-les dans app_constants par exemple, par exemple, user :: statut_pend => "en attente" . 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é.


3 Réponses :


9
votes

Je pense que vous pouvez le faire de cette façon: xxx

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 trans pour obtenir la version texte de l'état de l'utilisateur à partir de Utilisateur Domaine de localisation.

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.

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.


1 commentaires

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.



4
votes

Vous pouvez définir votre classe comme dans l'exemple suivant

ContactResource::getTypeList()


3 commentaires

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.



1
votes

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 Status_Pending , Status_Active , Statut_Suspendue 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 à: xxx

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é , à l'aide de l'Enum ci-dessus, l'entité se retrouverait comme suit: xxx

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: xxx

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: xxx

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: xxx

la fonction toarray n'est pas disponible dans Mabeenum \ Enumma, mais vous pouvez faire votre propre: xxx

résumer:

  1. Utilisez un énumé pour définir une liste de valeurs alternatives pour un seul champ.
  2. Créez une valeur d'un objet qui reçoit cette enum dans le constructeur si vous souhaitez ajouter des fonctionnalités spécifiques à VO sur ce champ.
  3. Utilisez une carte Enum pour servir les besoins de l'interface utilisateur.

2 commentaires

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.