[JAVA] Cela fait du bien d'avoir différentes classes pour les mêmes valeurs de table

introduction

Pour résumer l'histoire, il ne suffisait pas d'utiliser la même classe simplement parce qu'elles ont la même valeur.

Écrivons trois exemples légèrement différents. J'ai changé le contenu de traitement de manière appropriée, mais je lui ai fait la même configuration que la partie où j'ai eu du mal avec le service que je maintiens.

En fait, la conception de la classe est décidée sur la base de l'idée de DDD, mais cette fois, je dirai simplement que ce sera assez bon simplement en concevant le type.

Prémisse de l'article

Cas 1 Manipulez deux clés primaires

Par exemple, supposons qu'un téléphone portable d'entreprise prêté à un employé soit cassé et remplacé. Recevez le numéro de série que vous utilisez actuellement et remplacez-le par le nouveau numéro de série préparé.

Classes et implémentations

number_1.png (SerialNumber) et (SerialNumber, SerialNumber) sont sujets aux bogues.

number_3.png Étant donné que les deux numéros de série ne se distinguent que par le nom de la variable, il peut être compilé même avec (changé, changé). .. Ensuite, probablement en recherchant les données avec le premier argument, cela ressemble à une exception d'exécution telle que "Un tel numéro de série n'est pas prêté". (En aparté, je viens de remarquer, si je l'écris avec le complément de l'éditeur, je peux faire une erreur parce que les deux «changé» et «courant» sont de «c». Il est inattendu qu'une telle erreur soit un long mot)

Refactoriser

number_2.png Puisque domaines n'a qu'une seule classe de nombres, la manipulation est simple et se refactorise à la méthode d'identification de toutes les parties qui travaillent dur avec le nom de la variable courant et changé avec les classes actuel et changé. ..

number_4.png Ça fait du bien.

réellement

Finalement, il ira dans la même colonne de la même table, donc si vous allez à la couche aussi près que possible de la base de données, vous pouvez créer SerialNumber à partir de CurrentSerialNumber pour augmenter le degré d'abstraction.

Cependant, SerialNumber doit être préparé près deTable au lieu de domaines et doit êtreSerialNumber.from (CurrentSerialNumber) ʻau lieu deCurrentSerialNumber.toSerialNumber () . Si vous le générez avec to, domaindépend deTable, et domains vous permettra d'utiliser SerialNumber`.

Cas 2 Mettre à jour le statut d'une classe

Par exemple, supposons qu'il existe un système de gestion des membres qui accepte les retraits des membres. Lors du retrait de l'adhésion, définissez le statut de retrait et indiquez la date de retrait vide pour mettre à jour le statut.

Classes et implémentations

user_1.png Il est difficile de se rendre compte de la cohérence de «Status», et «0..1» est assez sujet aux exceptions d'exécution.

user_3.png Je ne sais pas quel ** membre j'ai obtenu de find (id), donc je le vérifie.

Après cela, même lorsque le statut de membre est retiré et rendu permanent, si le paramètre est erroné, quelque chose qui n'est pas retiré sera rendu permanent.

Refactoriser

user_2.png Si un tel système de mise à jour de l'état est transformé en une classe différente pour chaque état, une quantité considérable de mines terrestres peut être éliminée.

Les «membres non abonnés» ne peuvent être créés qu'à partir des «membres en cours d'utilisation», les «membres en cours d'utilisation» ont toujours une date de retrait et les «membres retirés» ont toujours une date de retrait.

user_4.png Vous pouvez être sûr que le résultat de «find (id)» est un «membre en cours d'utilisation». (Bien sûr, Table est responsable de la vérification à la place)

Puisque Table.unSubscribe () est une méthode uniquement pour se désabonner, il n'est plus nécessaire de passer Status.UnSubscribed, et la valeur de réglage pour la commodité du système ne provient plus de domaines.

réellement

Il existe diverses situations telles que la candidature, le changement de formulaire de contrat, le non-paiement des frais, le gel, etc., et ce ne sont pas seulement les membres mais aussi diverses classes qui ne peuvent se passer de la direction. Si vous essayez d'utiliser correctement tous les états avec seulement la valeur de réglage dans la même classe, ce sera si douloureux que l'exception d'exécution mourra car elle sera couverte par la vérification d'incohérence de la valeur de réglage et la vérification «facultative».

Même si j'utilise un langage typé, je ne profite pas de la compilation en premier, donc j'ai l'impression de savoir dans quelle langue j'écris ... ??

Il existe différents modèles ici, et compte tenu de la conception de l'événement, ce sera trop long, alors je viens de le présenter. (Je suis plutôt en train d'étudier la conception d'événements ...)

Cas 3 Avoir une classe de parents commune

Par exemple, supposons que toutes les opérations utilisateur doivent être enregistrées en tant qu'historique des opérations. Si vous effectuez un achat, enregistrez l'historique des demandes d'achat. En cas d'annulation, mettez à jour l'historique des applications sur annulé et créez un historique des opérations d'annulation.

opération Historique des applications Historique des annulations
Appliquer Peut faire n'existe pas
Annuler Mis à jour à annulé Peut faire

C'est compliqué, mais ça ressemble à ça.

Classes et implémentations

operation_1.png «Depuis Application» et «Annulation» sont traités différemment, les classes sont séparées, mais il est également pratique de le gérer comme un historique des opérations à des fins générales, donc un exemple de création d'une classe parente.

operation_3.png Comme c'est compliqué à faire, il existe de nombreuses valeurs de réglage, et comme tout est enregistré sous .save (), il est possible que la valeur et le nombre de fois soient erronés.

Refactoriser

operation_2.png Afin de gérer correctement l'application et l'annulation lors de la compilation tout en quittant la classe commune, il semble bon de séparer la classe parente.

operation_4.png Si vous utilisez une méthode dédiée de la même manière que le retrait, vous pouvez presque éliminer la valeur définie. En changeant .save () en .cancel (appliqué, annulé), vous pouvez toujours mettre à jour les deux correctement.

réellement

Finalement, l'historique des opérations tombe pour s'annuler ou se terminer. Après avoir postulé, vous pouvez commencer à l'utiliser après avoir confirmé qu'il est arrivé. La raison de la création d'un historique d'annulation distinct est qu'il sera nécessaire d'accepter les remboursements à partir de maintenant, et l'annulation sera terminée lorsque le traitement nécessaire sera terminé.

En termes d'image, la forme finale ressemble à ceci.

opération Historique des applications Historique des annulations
Appliquer Peut faire n'existe pas
Atteindre Achevée n'existe pas
Annuler Mis à jour à annulé Peut faire
Rembourser Reste annulé Achevée

Fondamentalement, c'est sous cette forme, mais il y a autant d'histoires d'opérations que de services fournis, tels que la mise à jour des informations sur les membres et l'achat d'équipements supplémentaires.

Il est extrêmement difficile de les mettre à jour correctement à chaque fois, j'aimerais donc bénéficier de la puissance de la compilation lors de la préparation de certaines classes parentes.

Résumé

Politique de base

Un signe qui semble dangereux

Faire face

Que faire comme position de base

Quelque chose comme ca.

Recommended Posts

Cela fait du bien d'avoir différentes classes pour les mêmes valeurs de table
Ce dont les ingénieurs Java ont besoin pour se préparer à la version Java 11
Je souhaite renvoyer plusieurs valeurs de retour pour l'argument saisi
"Attendez que le processus se termine" et arrêtez le processus car il reste