Existe-t-il un modèle de conception pour gérer de profondes relations plusieurs-à-plusieurs?

10

J'ai du mal à définir ce modèle de données que j'ai rencontré en travaillant sur plusieurs applications.

Cela consiste en:

  1. Un type d'objet composé de nombreux objets lui-même
  2. Un deuxième type d'objet, où chaque instance «a plusieurs» du premier objet
  3. Et, chacun des sous-objets du premier objet est modifiable pour chaque association au deuxième type d'objet.

Un exemple simple pourrait être:

  1. Un cours de programmation composé d'un ensemble de leçons
  2. Les leçons sont composées d'un ensemble de devoirs.
  3. Un cours peut être attribué à un étudiant.
  4. Cependant, une fois qu'un cours est attribué à un étudiant, chaque leçon et / ou devoir peut être personnalisé pour cet étudiant, avec des suppressions et des ajouts, au point où le cours d'origine peut être méconnaissable.

Dans mes solutions, cela se traduit par:

Lors de l'attribution d'un cours à un étudiant, le cours est chargé en mémoire. Ensuite, pour chaque sous-objet, un objet de relation élève / sous-objet est généré avec les métadonnées appropriées. Essentiellement, j'utilise l'objet d'origine comme modèle pour générer les objets personnalisables requis.

Il en résulte une énorme quantité de données à mesure que les sous-objets deviennent plus complexes et numérotés. Je me demande s'il y a une optimisation ou un modèle pour réduire la quantité de logique / complexité requise pour manipuler ce modèle de données.

Nicholas Pickering
la source
2
Voulez-vous vraiment "réduire la quantité de données"? Recherchez-vous plutôt des moyens de "réduire la quantité de code et de logique non triviaux" qui doivent être écrits pour implémenter le comportement requis? (Je remarque que la gestion continue des données nécessite une structure de données relationnelles, semblable à une base de données.)
rwong
@rwong Oui, "réduire [la quantité] de code et de logique non triviaux" est mon objectif final. Pour moi, cela signifie réduire la complexité des données d'une certaine manière, mais ce n'est pas nécessairement une exigence. C'est devenu un modèle de données si commun que je me demande s'il existe un moyen plus simple de le gérer.
Nicholas Pickering,
1
Il s'agit en principe d'une version améliorée d'une relation m: n. Qu'en est-il d'un titre comme »Comment gérer des relations d'objets complexes«?
Thomas Junk
1
Une énorme quantité de données n'est pas la même chose qu'un énorme niveau de complexité dans les données. La difficulté à gérer ce que vous construisez augmentera probablement avec la complexité plus qu'avec le volume.
Walter Mitty
1
Intéressant. J'ai travaillé sur plusieurs applications qui ont ce modèle, mais je n'ai jamais repéré auparavant que c'est un modèle. J'aimerais également voir des moyens plus simples de gérer ce type de données.
Jules

Réponses:

6

Je vois quelques options en fonction de ce dont vous avez besoin: (1) s'il existe de nombreuses instances uniques qui suivent un algorithme commun, (2) s'il existe de nombreux objets similaires ou si vous générez des objets au moment de l'exécution, et (3) si vous souhaitez modifier dynamiquement le comportement de l'objet lors de l'exécution. Remarque: vous pouvez combiner tous les modèles que je mentionne ici, si nécessaire.

  1. Si chaque "deuxième type d'objet" est unique mais suit un modèle de comportement similaire, vous pouvez utiliser le modèle de modèle . Il semble que vous fassiez cela. Mais pour le rendre explicite, votre classe de base abstraite a un algorithme général programmé; certaines étapes de cet algorithme sont implémentées dans les classes dérivées.

  2. Si vous créez de nombreux objets ou si la création d'objets au moment de l'exécution est importante pour vous, vous pouvez utiliser Factory Pattern .

  3. Et si vous souhaitez modifier dynamiquement le comportement, le modèle de stratégie peut fonctionner. Par exemple, si un étudiant dans un programme régulier est décidé pour des besoins spéciaux ou pour suivre un programme accéléré. Cela fonctionne en composant «l'étudiant» d'un objet qui représenterait une classe de base du programme. Le programme serait attribué à un programme dérivé lors de la construction de l'étudiant (cela semble étrange) et pourrait être réaffecté à un autre programme dérivé plus tard.

(Juste pour info, si vous utilisez (3) Strategy Pattern avec C ++, vous devrez Rvalues ​​pour la composition.)

Pour stocker vos objets et vos seconds objets, il peut être utile d'envisager le modèle d'itérateur (pour les parcourir, les ajouter, les supprimer, les trier, etc.).

Une bonne référence est Head First Design Patterns , qui couvre les modèles que je mentionne et leur mise en œuvre. Ils travaillent en Java.

Audrow
la source
0

J'ai du mal à croire, sous la présence d'un magasin de données ou d'une persistance, que vous auriez besoin d'avoir des objets avec ce type de profondeur à un moment donné dans un run-time. Est-ce pour les GUI CRUD? Si oui, je suggérerais de changer votre approche dès le départ. C'EST À DIRE:

Identifiez la sous-structure nécessaire pour que l'étudiant affiche, et stockez avec état son index d'origine dans la base de données, et mettez-le à jour sans état , en allant vers ou depuis la vue et la base de données principale.

John P. Feltz
la source
Je ne suis pas sûr de comprendre votre suggestion. Je dois générer un sous-objet vide, puis forcer l'utilisateur à un autre formulaire qui lui permet de modifier le sous-objet?
Nicholas Pickering
Je suggère que les objets en eux-mêmes n'accomplissent pas grand-chose, si tout ce que vous faites est une transaction sans état entre leur contenu et une base de données principale. Si tel est le cas, supprimez-les et effectuez simplement la transaction pour les données spécifiques à ce que le client doit faire.
John P. Feltz
Modifier: cela peut également signifier la création d'objets pour capturer ces données particulières en cours de transaction - si vous êtes biaisé par ORM en raison de leur commodité à cet égard.
John P. Feltz
À moins que je ne comprenne mal, je ne pense pas que le processus puisse devenir apatride. Tout dépend du contexte de l'action de l'utilisateur. Lorsqu'un utilisateur crée un objet principal, il s'attend à ce que la sous-structure soit disponible pour être modifiée immédiatement.
Nicholas Pickering, le
-1

Un cours personnalisé pour chaque étudiant au point où le cours d'origine est méconnaissable suggère que le cours d'origine est simplement une référence «par défaut». Ce que je ferais, c'est créer une classe appelée CustomizedCourse (ou une liste d'entre eux) et avoir cela (ou une liste de cela) comme propriété d'un étudiant. Le cours personnalisé peut avoir une référence au cours d'origine pour une utilisation «référentielle», mais le travail et les données principaux se trouveraient dans le cours personnalisé lui-même.

frezq
la source
downvoter soin de commenter?
frezq
Je n'ai pas downvote (je suis l'OP), mais il semble que vous essayez de décrire le modèle ou le modèle de stratégie qui ont déjà été décrits dans une autre réponse.
Nicholas Pickering