2010-01-20 19 views
6

J'ai de la difficulté à faire le tour des objets métier ou, plus spécifiquement, des collections d'objets métier.Objets métier et collections C#

Voici un exemple rapide de ce que j'essaie de faire.

Si j'ai un objet incident, cet objet peut avoir un nombre de personnes impliquées et chacun de ces objets Person peut avoir plusieurs notes. Les notes ne peuvent pas exister sans un objet Personne et les objets Personne ne peuvent pas exister sans un objet Incident.

Si j'ai la liste publique < Note> notes = nouvelle Liste < Note>() alors des méthodes telles que ADD et REMOVE deviennent disponibles pour la personne dans Incident. Je suppose que si j'appelais ces méthodes sur la collection Notes, il le supprimerait simplement de la liste mais n'exécuterait aucun code pour réellement ajouter/mettre à jour/supprimer l'employé de la source de données. Cela m'amène à croire que je ne devrais pas utiliser List mais quelque chose d'autre?

Cela m'amène aussi à une autre question. Où devraient résider les opérations réelles de la base de données CRUD? Un objet Note doit-il avoir son propre CRUD ou l'objet Person doit-il en être responsable puisqu'il ne peut pas exister sans lui?

Je suis un peu perdu sur la voie à suivre et j'aimerais bien avoir cette partie car elle servira de modèle pour le reste du programme.

+1

Awesome question liée à la POO va certainement aider les autres +1! – JonH

Répondre

1

Une bonne information a été donnée, mais une chose que vous avez dit que peut-être vous source de confusion est ceci:

« Si j'ai Liste publique note = new Liste() puis des méthodes telles que ADD, REMOVE devient disponible pour la Personne dans Incident. "

Tout dépend de la façon dont vous concevez vos classes. Une chose que vous devriez penser est la façon dont ces données se rapportent les unes aux autres. Cela vous aidera à imaginer votre conception de classe.

Cela ressemble à ce qui suit:

  • Un incident peut impliquer de nombreuses personnes
  • Une personne peut créer beaucoup de notes
  • Une note est le niveau et existe plus bas en raison d'un incident en cours de création et responsable (s) travaillant sur cet incident.

Incident 1 - nombre de personnes

Personne 1 - de nombreuses notes

Vous pouvez faire ce type de relation dans un certain nombre de façons. Une façon peut être de séparer les objets impliqués, puis de créer des objets joints.

Par exemple

public class Incident { 
//insert incident fields here 
//do not add person logic/notes logic 
//probably contains only properties 
} 

public class Person { 
//insert person fields 
//private members with public properties 
//do not embed any other logic 
} 

public class Comment { 
//insert comment private fields 
//add public properties 
//follow the law of demeter 
} 

Ces classes ne donnent pas de détails les uns aux autres, ils ne sont que repositories pour stocker ces informations. Vous relier ensuite ces classes les uns aux autres, par exemple

public class IncidentPersonnel { 
List<Person> p; 
//add methods to add a person to an incident 
//add methods to remove a person from an incident 
.... 
} 

alors vous pouvez avoir une autre classe la manipulation du commentaires par le personnel

public class PersonnelNotes { 
List<Note> n; 
//other methods... 
} 

Vous pouvez aller plus loin avec cela, mais il peut compliquer les choses, mais je suis juste vous donner une autre idée de la façon de gérer cela.

Essayez de suivre the law of demeter for functions

Encapsulate tous vos objets, en plus, votre voisin peut vous parler, mais pas beaucoup d'autre ... Cela aidera à garder vos classes à couplage lâche et rend le processus de pensée un peu plus simple pour toi. Enfin, vous avez mentionné comment les opérations CRUD devraient fonctionner. Tout cela revient à votre DAL (Data Access Layer). Plutôt que renvoyer des lignes de données à partir d'une table, vous pouvez ensuite renvoyer un objet référencé avec tous ses attributs. Ajoute et supprime le travail de la même manière (en entrant ou en sortant un objet). Vous pouvez utiliser un ORM ou écrire votre propre DAL. Tout dépend de la façon dont vous voulez vous impliquer :).

+0

Juste une note que c'est juste une façon de gérer cela. Cependant, cela peut sembler le plus logique pour les autres développeurs. – JonH

+0

Bonne info, merci. J'ai une dernière question. Liste dans PersonnelNotes est actuellement privé. Si je voulais une liste des notes pour cette personne je retournerais une liste de roi de readonly et si j'appelais DeleteNote sur PersonnelNotes, il appellerait le DAL pour le supprimer et reconstituer alors la liste en lecture seule? – Mathew

+0

Certainement devrait être privé, si vous voulez supprimer une note de la liste que vous pouvez faire n.Remove (YourIDRepresentationOfANote). Même si la liste n'est pas explicitement en lecture seule, vous pouvez toujours la rendre en lecture seule à tout moment. Une fois que vous l'avez retiré de la liste, vous pouvez alors appeler votre DAL en passant dans l'IDentifier de la note pour le retirer de la base de données. – JonH

1

Vous avez plusieurs questions différentes en un ici, je vais essayer de répondre le plus.

En ce qui concerne les problèmes en utilisant List<T> - le cadre a une ReadOnlyCollection<T> qui est utile dans exactement votre situation. Ceci est une collection qui ne permet pas d'ajouter ou de supprimer une fois créée. En ce qui concerne la responsabilité des opérations CRUD - qui devrait appartenir à votre couche de données, aucun de vos objets (voir SRP - Principe de responsabilité unique).

+1

Vous pouvez également convertir une liste en lecture seule à l'aide de sa méthode AsReadOnly() - http://msdn.microsoft.com/fr-fr/library/e78dcd75.aspx –

+0

Cela nécessiterait donc un objet d'accès aux données séparé pour chaque objet métier ? Il y aurait toujours quelque chose comme AddNote, RemoveNote dans l'objet Person et quand ils sont appelés, ils demanderaient au DAL de faire le travail? – Mathew

+0

La classe Personne par elle-même ne devrait avoir aucune connaissance sur une note. Il ne connaît qu'une personne, et c'est tout ce qui devrait l'intéresser. Voir mon message pour plus d'informations. – JonH

1

La façon dont je le fais est: chaque objet qui a des objets enfants contient une liste d'entre eux, et chaque objet avec un parent contient une propriété avec son type. L'ajout est effectué en remplissant un objet (ou une hiérarchie d'objets) et en l'envoyant au DAL pour la persistance si désiré. Les opérations CRUD sont toutes dans la couche DAL, qui est indépendante des types d'objets mais utilise ces types pour déterminer les tables, colonnes, etc. auxquelles accéder. La suppression est la seule chose traitée différemment en définissant la propriété Deleted d'un objet qui déclenche le DAL pour le supprimer.

Maintenant en ce qui concerne la logique métier - il ne pas résident avec les objets eux-mêmes (les OTI), mais il est fait par les classes qui reçoivent ou recueillent ces OTI si nécessaire, effectuer leur travail et envoient les OTI vers le DAL pour les mises à jour.

Questions connexes