2009-05-18 6 views
0

Disons que j'ai une classe Farmer et qu'un fermier a une collection de cochons.Classes ORM avec collections; essayer de maintenir l'accent sur la classe parente plutôt que sur les enfants

Si j'utiliser un ORM comme Hibernate, je peux en cascade mises à jour de la collection Pig d'un agriculteur, de sorte que je peux faire quelque chose comme ça de mon contrôleur:

Pig pig = new Pig("Charlie"); 
farmer.addPig(pig); 
farmerService.save(farmer); 

Mon service agriculteur ne sait rien Les cochons. Selon les exigences de l'application, je n'aurais peut-être même pas besoin d'un DAO Pig du tout. Je ne suis concerné que par les agriculteurs. Cool, mais que se passe-t-il quand un cochon est transformé en bacon?

farmer.removePig(pig); 
farmerService.save(farmer); 

Le problème ici est que dans une application web sans état je besoin d'un moyen de créer un porc que je vais passer à une méthode removePig Farmer.

que je pouvais faire:

// manual search Farmer's collection - requires loading all pigs. 
// Yes, I could just pass id to removePig, but it confuses the example 
pig = farmer.getPigById(id); 
farmer.removePig(pig); 
farmerService.save(farmer); 

ou

// loads up a pig, and hopefully it belongs to the farmer 
pig = farmerService.getPigById(id); 
farmer.removePig(pig); 
farmerService.save(farmer); 

Ce dernier semble mieux, mais si je vais ajouter une méthode getPigById() à mon Farmerservice, je pourrais aussi juste avoir une méthode savePig(). Cela changerait l'orientation de l'agriculteur au porc.

pig = farmerService.getPigById(id); 
farmerService.removePig(pig); 

Aha, et regardez c'est encore moins de code. Cependant, cela viole l'idée logique de vouloir travailler avec les agriculteurs et leurs collections de porcs, pas les porcs individuels. Je ne supprime plus explicitement un porc d'un fermier, tout est implicite et en arrière.

Il semble que je rencontre beaucoup ce problème. La classe qui devrait être mise en évidence est Farmer. Les cochons sont secondaires. Mais il est difficile de travailler avec des collections de porcs sans glisser dans la pente pour travailler avec des porcs individuels dont les changements sont simplement reflétés lorsque les agriculteurs sont rechargés de la persistance.

Quels conseils pouvez-vous m'offrir à ce sujet?

Répondre

1

Dans le scénario, j'ai tendance à pencher vers votre 2ème approche. Le fait que vous êtes dans un environnement moins d'état ne doit pas être reflété dans votre modèle d'objet, seulement dans la façon dont vous restaurez votre état dans une requête http particulière. Cela se fait ici:

pig = farmerService.getPigById(id); 

Ce code devrait se produire dans le contrôleur (MVC ou dans les modèle MVP). Puis le reste du code continue comme vous le feriez normalement:

farmer.removePig(pig); 
farmerService.save(farmer); 

Le contrôleur particulier qui est la manipulation devrait être responsable du maintien de cet état du porc actuel étant considéré comme la demande actuelle. Il devrait être responsable de l'envoi d'un id de porc au navigateur, et responsable de la traduction de cet id de porc dans un objet cochon. La façon dont elle le fait est la sienne, mais l'utilisation de l'appel au service des agriculteurs est la plus logique. À partir de là, vous pouvez automatiser davantage cette traduction en ayant un appel général d'identification d'objet à objet et vice versa.

Votre pensée que ce modèle de domaine devrait être agriculteur concentré est correct et va en ligne avec la conception axée sur le domaine. La classe agriculteur dans ce cas est un agrégat de porcs, et définit donc une limite autour d'un ensemble de porcs. Tous les accès des porcs doivent passer par l'agriculteur. De cette façon, vous avez un contrat clair sur la façon dont les cochons sont créés, détruits et modifiés. Votre dernière approche n'est donc pas aussi saine que celle d'avant.

+0

Cela fait beaucoup de sens pour moi, merci! – Boden

Questions connexes