La programmation d'un un-à-plusieurs relations
Donc je suis surpris qu'en faisant une recherche sur google et stackoverflow ne renvoie plus de résultats.
Dans la programmation orientée-objet (je suis à l'aide de java), comment voulez-vous mettre correctement en œuvre un un-à-plusieurs relation?
J'ai une classe Customer
et de la classe Job
. Ma demande est pour une société fictive, qui complète emplois pour les clients. Mon actuel de la mise en œuvre est donc que le Job
classe n'a rien à voir avec la Customer
classe, il n'y a aucune référence à tous. Le Customer
classe utilise une collection et des méthodes pour contenir, récupérer et modifier les informations sur les Emplois qui leur ont été attribués par et/ou réalisé pour un client.
La question est, est ce que si je voulais trouver de qui client un particulier Job
a été fait? J'ai trouvé cet article qui est pertinent: http://www.ibm.com/developerworks/webservices/library/ws-tip-objrel3/index.html.
En fonction de la mise en œuvre de l'auteur, je laisserais le Job
constructeur de prendre un Customer
paramètre, et de les stocker afin que je puisse le récupérer. Cependant, je ne vois aucune garantie que ce modèle peut être cohérente. Il n'y a pas restirctions à l'ensemble de la clientèle d'un emploi en tant que client que le travail n'était pas, et d'ajouter des tâches aux clients qui ont été fait pour quelqu'un d'autre. Toute aide serait appréciée.
OriginalL'auteur MarioDS | 2012-04-10
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas 100% infaillible moyen de maintenir l'intégrité.
L'approche qui est généralement adoptée consiste à utiliser une méthode pour construire la relation et de construire le sens d'autres dans la même méthode. Mais, comme vous le dites, cela ne veut pas garder quelqu'un de jouer avec elle.
La prochaine étape serait de faire certaines des méthodes du package accessible, de sorte qu'au moins un code qui n'a rien à voir avec les vôtres ne peut pas le casser:
En réalité, vous n'aurez pas souvent le modèle de cette relation dans vos classes. Au lieu de cela, vous allez chercher tous les enfants d'un parent dans une sorte de référentiel.
N'est-il pas une faute de frappe dans la Mère, il y a deux méthode addChild() méthodes
bonne prise. Corrigés.
Quelles seraient les objets dans le référentiel? Je suppose que ce serait qqch comme
ParentChild{Parent p, Collection<Child> c}
etRepository{ Collection<ParentChild> pc; returnParents(Child c){...}; returnChildren(Parent p){...} }
.ce serait quelque chose comme Référentiel{ Collection<Enfants> getAllForParent(père, Mère, parent)}
OriginalL'auteur Joeri Hendrickx
Peut-être que vous ne vous attendez pas à un complexe (et zéro-code) de réponse, mais il n'y a pas de solution pour construire votre robustesse de l'API de la façon dont vous souhaitez qu'il. Et ce n'est pas parce que le paradigme (OO) ou la plate-forme (Java), mais seulement parce que vous avez fait une mauvaise analyse. Dans un transactionnelles monde (chaque système que les modèles réels problèmes de la vie et de leur évolution au fil du temps est transactionnelle) Ce code ne sera jamais rompre à un certain point:
parce qu'à l'époque
j1.someProperty
est accessible,j1
etj2
ne pourrait même pas exister 🙂TL;DR
La longue réponse à cette question est immutabilité, et il introduit également les notions de cycle de vie et transactions. Toutes les autres réponses vous dire comment faire, je tiens à souligner pourquoi. Un un-à-plusieurs relation a deux côtés
Votre système est compatible tant que si le Client
A
d'EmploiB
, le TravailB
appartient au ClientA
. Vous pouvez mettre en œuvre dans un certain nombre de façons, mais cela doit se faire dans un transaction, c'est à dire une action complexe faite de celles qui sont simples, et le système doit être unavailble jusqu'à ce que la transaction a fini de l'exécution. Cela vous semble trop abstrait et sans rapport avec votre question? Non, il n'est pas 🙂 Un système transactionnel s'assure que les clients peuvent accéder au système d'objets uniquement si tous ces objets sont dans un état valide, donc seulement si l'ensemble du système est cohérent. D'autres réponses que vous voyez la quantité de traitement nécessaire pour résoudre certains problèmes, de sorte que la garantie a un coût: performance. C'est la simple explication de Java (et à d'autres fins générales de l'OO langues) ne peut pas résoudre votre problème hors de la boîte.Bien sûr, un langage OO peut être utilisé pour modéliser une transactionnelle monde, et y accéder, mais des précautions particulières doivent être prises, certaines contraintes doivent être imposées et d'une programmation spéciale le style requis pour client développeurs. Habituellement, un système transactionnel offre deux commandes: de recherche (aka requête) et de verrouillage. Le résultat de la requête est immuable: c'est une photo (c'est à dire une copie) du système au moment très précis, il a été pris, et la modification de la photo a évidemment aucun effet sur le monde réel. Comment peut-on modifier le système? Généralement
(BTW, vous pouvez voir comment le concept de cycle de vie appliquées aux locaux et à distance des objets?)
Vous pouvez aller avec
Set
s,final
modificateurs et ainsi de suite, mais jusqu'à ce que vous introduire des transactions et de l'immuabilité, votre conception d'une faille. Habituellement, les applications Java sont soutenus par une base de données, qui fournit des fonctionnalités transactionnelles, et souvent à la base de données est couplée avec un ORM (tels que la mise en veille) pour l'écriture de code orienté objet.Je voulais juste souligner l'importance de la phase de conception: vous pouvez modéliser un système de différentes façons étant donné un ensemble de ressources (temps, $$$, des connaissances), mais chaque solution aura ses limites et vous avez à rendre explicite, parce que , même les plus simples, on peut être le meilleur, mais vous devez soigneusement énoncent les exigences, les limites et la portée 🙂
OriginalL'auteur Raffaele
Vous pouvez vous assurer qu'il n'y a pas de doublons à l'aide d'un Ensemble mise en œuvre comme HashSet au lieu d'utiliser d'autres structures de données.
Et au lieu d'ajouter Travail à un client, créer une finale intérieure de la classe dans la catégorie d'Emplois a constructeur privé. Que de s'assurer que l'enveloppe intérieure ne peut être créé que par un objet de la tâche. Vous faire de l'Emploi constructeur de prendre en jobID et le client en tant que paramètre. Pour maintenir la cohérence,- si le client est Null jeter l'Exception en tant que mannequin d'emplois ne devrait pas être créée .
Dans ajouter méthode de la Clientèle, vérifier pour voir si le Travail enveloppé par JobUnit a le même ID de client comme son propre id, si ce n'est jeter l'Exception.
Lors du remplacement d'un client en classe d'Emploi retirer la JobUnit à l'aide de la méthode fournie par le Client de la classe et d'ajouter lui-même à la nouvelle clientèle et de modifier le client de référence pour le nouvellement adoptée à la clientèle.
De cette façon, vous pouvez raisonner avec votre code mieux.
Voici ce que votre client de classe pourrait ressembler.
Et la Classe d'Emploi:
final JobUnit unité;
Une chose, mais je suis curieux de savoir pourquoi avez-vous encore besoin d'ajouter des tâches à un client de l'objet?
Si vous souhaitez vérifier est de voir que le client a été assignée d'emploi, il suffit de l'inspection du Travail vous donnera cette information. En général j'essaie de ne pas créer des références circulaires, à moins inévitable.
Aussi en cas de remplacement d'un client à partir d'un emploi une fois qu'il a été créé n'est pas nécessaire, il suffit de faire le champ client Final dans le Travail de classe et de supprimer la méthode de ensemble ou remplacer.
La restriction de l'attribution de la clientèle pour un travail doit être maintenu dans la base de données et la saisie de données doit être utilisé comme un remède.
Comme pour l'ajout d'emplois à la clientèle qui ont été fait pour quelqu'un d'autre, vous pouvez vérifier pour référence client dans un travail pour s'assurer que le client pour lequel un travail est en cours d'ajout est le même que celui qu'elle détient ou encore mieux-simplement supprimer toute référence à la clientèle pour le Boulot et ça va simplifier les choses pour vous.
OriginalL'auteur anzaan
Si l'objet Client est propriétaire de la relation, alors vous pouvez éventuellement faire de cette façon:
...si la propriété est dans l'autre sens, en remplaçant simplement le client pour le travail.
L'idée est d'avoir le propriétaire de la relation de maintenir la cohérence. Bi-directionnel relations impliquent généralement la gestion de cohérence se trouve dans les deux entités.
...ou vous pouvez vous rendre explicite de l'emploi.setCustomer (voir édité réponse)
OriginalL'auteur Ryan Fernandes
Faire un bon poseur-fonction qui permet de maintenir la cohérence. Par exemple, lorsque vous créez une tâche, vous devez fournir le client dans le constructeur. Le travail de constructeur, puis ajoute à la clientèle de la liste de tâches.
Ou chaque fois que vous ajoutez une tâche à un client, l'ajout d'une fonction pour vérifier que le travail du client est le client, c'est d'être ajoutés.
Ou une combinaison de cela et les choses semblables à ce qui convient à vos besoins.
customer.addJob(new Job(this, a, b, c));
sera le résultat du travail d'être ajouté deux fois. Et votre solution crée le besoin pour une méthode publique comme ça, donc...Ensuite, ne pas l'appeler de cette façon, il suffit de faire de nouveaux Emplois(ce, ..)
Mon souci n'est pas que la cohérence est garantie lorsque vous n'avez pas le casser en vous-même. Vous avez raison dans tous les sens, bien sûr, mais je veux faire mes classes dans une telle manière que n est par programmation en mesure de briser la cohérence, non seulement parce qu'ils ignorent une méthode publique. Les deux méthodes et les constructeurs ont besoin d'être 100% utilisable dans tous les cas un programmeur peut utiliser.
Je ne peux pas répondre à votre commentaire sur l'autre réponse, comme je suis nouveau ici, donc, ici, il va: si vous avez une fonction publique dans l'emploi de modifier le client, cette fonction est de maintenir la cohérence par la suppression de lui-même à partir de l'ancien client et en ajoutant à la nouvelle.
Je vous remercie de votre aide et de comprendre ce que vous essayez de l'expliquer, mais je ne suis pas sûr de comprendre les problèmes qui pourraient se produire avec cette solution. Je vais travailler un peu plus sur elle, et voir où je vais.
OriginalL'auteur Matsemann
Mettre en œuvre une sorte de collection à l'objet qui a les autres objets
Par exemple, vous pourriez dire:
puis en utilisant les getters et les setters vous pouvez ajouter les valeurs des emplois à cette liste.
C'est de base OO choses, je ne pense pas que vous avez cherché assez sur l'internet. il y a beaucoup d'informations disponibles sur ces sujets.
Btw, vous pouvez utiliser toutes sortes de collections (Ensembles, Listes, Cartes)
Apparntly j'ai été rapide à répondre parce que j'ai raté l'essence de la question. Oups, excuses les plus sincères:)
Pas de problème. La baisse de vote n'était pas le mien, parce que votre réponse n'était pas incorrecte ou hors de propos.
OriginalL'auteur steelshark
Je sais que c'est tard, mais je pense qu'un autre moyen pour cela serait de regarder le problème un peu différemment. Depuis le client détient une collection de tous les emplois attribués par ou réalisé pour un client, vous pourriez envisager de la catégorie d'emplois à une sous-classe de client avec des informations supplémentaires d'avoir toutes les tâches accomplies par le client. Ensuite, vous n'avez qu'à maintenir l'id du client dans la classe principale, et il serait héréditaire. Cette conception permettrait de s'assurer que chaque tâche peut être lié à un client. Aussi, si un client vous voulez savoir combien d'emplois sont présents que trop également être obtenu.
OriginalL'auteur prashant
Je suis désolé, je sais que c'est très tard, mais j'ai rencontré un problème similaire où je sens la meilleure solution est de suivre un modèle d'héritage. Pense de travail comme étant des emplois fait/asisgned par un client en particulier. Donc, dans ce cas, le Client en serait une super classe avec le Travail(Permet d'appel est à la clientèle de l'emploi) est une sous classe depuis un Travail ne peut pas exister sans un client. Un client aurait également une liste des emplois principalement pour la facilité de récupération de données. Intutively cela n'a pas de sens, de l'Emploi et de la Clientèle de fait semblent avoir aucun rapport, cependant, une fois que vous voyez que le Travail ne peut pas exister sans un client, il devient simplement une extension de la clientèle.
toString()
sur ce qu'est ce qu'il va afficher? C'est une violation du principe de responsabilité unique. En tout cas, vous avez complètement ignoré la collection qui est la source de risque d'incohérence.Ok, tout d'abord sur l'appel à toString (), vous pourriez pring les valeurs actuelles et les super-classes toString() et ne pas la collection. La collection n'est présent que pour stocker plusieurs enfants, il n'a pas besoin d'être présent dans toString(). Concernant la responsabilité unique alors qu'est convaincu que la customerJob de catégorie a opérations liées à customerJob et pas autre chose. Le point ici est, depuis customerJob ne peut exister sans un client, je ne vois aucun point en ayant une composition depuis un customerJob est une extension du client. Veuillez préciser quel est le problème au lieu de simplement downvoting.
Vous avez une fausse idée sur ce que l'héritage est. Je ne peux pas exister sans la nourriture, l'eau, la planète terre. Je ne suis pas une extension de l'un d'eux. Mais philosophique des violations du principe de moindre étonnement de côté. Si un emploi hérite du client le client est en instance au sein de l'instance de travail est de 1 pour 1 relation. Désolé, mais cela n'a aucun sens.
Ok, quand vous dites que vous ne peut pas exister sans la nourriture et de l'eau, vous parlez de la vie. Mais ce que je veux dire, c'est que si le Tigre s'étend de l'Animal et il n'y a pas d'animal alors il n'y a pas de tigres qui est le cas regaring Client et de l'Emploi (c'est à dire il n'y a pas de client d'emploi, sans emploi). La deuxième partie de ce que vous dites, je suis d'accord cependant dans ce cas, si nous établissons une composition relation puis nous manquer l'héritage de la partie qui, je crois, doit être capturé, donc si nous conserver l'héritage et de maintenir le nombre de relation à l'aide d'une collection puis de l'OMI, nous avons pu obtenir le meilleur de deux mondes
L'héritage serait ce qu'une entité contient toutes les données se doit, ainsi que la collection serait de créer beaucoup besoin de beaucoup pour une relation. La classe serait encore seulement ont une responsabilité et pour toutes ses opérations, elle serait d'utiliser la inehritance modèle et non le nombre à une relation. Cependant, tout en étant utilisé comme un DTO il peut stocker une liste d'enfants, ce qui n'exigeant pas une structure supplémentaire pour stocker une liste d'enfants
OriginalL'auteur prashant