2009-06-16 4 views
13

Dans mon application pour le moment j'ai (comme dans tant d'autres applications) une entité appelée Contact, qui représente toute personne. À son niveau le plus basique, il est utilisé pour représenter les contacts d'affaires. Cependant, il peut également être utilisé pour représenter les employés de l'entreprise. et il y a aussi quelques types spéciaux d'employés (disons qu'il y en a un appelé Manager)Est-il toujours valide de convertir un objet d'une classe de base à une sous-classe

J'essaye de modéliser cela comme une relation d'héritage qui a du sens. Les employés ont des noms et des adresses, tout comme les contacts, ainsi qu'un certain nombre d'attributs liés à l'emploi. Les gestionnaires ont également un certain nombre d'attributs spécifiques au gestionnaire.

La difficulté vient quand un employé est promu à un gestionnaire. Est-il autorisé à convertir la classe de base Employee à la classe héritière Manager? C'est mal. Je suppose que je le ferais avec un constructeur spécialisé sur Manager. En plus, NHibernate supporte ce genre de comportement? est-ce aussi simple que d'obtenir l'employé, de créer le gestionnaire de l'employé, puis de sauver le gestionnaire?

Répondre

5

Tant que votre modèle d'entreprise correspond à votre domaine, vous faites le bon choix.

Cependant, il me semble que vous devriez avoir quelque chose comme:

Manager Promote(Employee employee) 
{ 
    var manager = new Manager(); 
    //promote your employee to a manager here 
    return manager; 
} 

dans un processus de flux de travail de quelque sorte. En ce qui concerne NHibernate, il semble que vous mélangez votre logique ORM avec votre domaine d'activité. La promotion d'un employé auprès d'un gestionnaire est une construction de domaine métier et, en tant que telle, appartient à votre modèle d'entreprise. Cependant, comment NHibernate mappe vos employés et vos gestionnaires dans votre base de données n'a rien à voir avec votre modèle d'affaires, sauf pour les cartographier. Cependant, cela n'a absolument rien à voir avec la façon de promouvoir un employé auprès d'un manager.

+0

La question de NHibernate était juste de savoir si NHibernate se plaignait de sauver un objet en tant que sous-classe quand il a été récupéré en tant que type de base. –

2

Je voudrais personnellement avoir une classe de base avec toutes les choses de base et une liste de rôles.
Chaque rôle a ses propres propriétés et fonctionnalités.
Les avantages sont deux fois:

  • Il est facile de donner ou de prendre un rôle à/d'une personne
  • Il permettra à vos gens d'avoir des rôles multiples sans avoir à faire « des classes mixtes »

Si vous allez avec un seul inherritance aller avec inherritance va bientôt vous rendre avec des cours comme « ManagerProgrammer », « ProgrammerStockManager », « ProgrammerSupport »

16

je partirais avec composition sur inheri dans ce cas. Si vous respectez l'héritage, vous changerez de classe à chaque promotion ou rétrogradation et chaque fois que vous embauchez un contact ou qu'un employé quitte le service et devient un contact régulier.

Il est plus facile de dire que les contacts ont des rôles. Vous pouvez ajouter un rôle de gestionnaire à un contact pour le promouvoir et supprimer le rôle pour le déclencher.

+1

Cela devrait être marqué comme la bonne réponse – Pierreten

0

G'day,

Si vous trouvez que vous devez convertir une classe dérivée d'un type à un autre type dérivé alors qui est une odeur que la conception initiale a des problèmes. Mon instinct ici est que vous représentez un objet Manager incorrectement.

Revenez aux notions de base et pensez aux termes OO où votre classe de base (Contact) contient les éléments communs des objets Employee et Manager. Les objets dérivés ne sont que des spécialisations de la classe de base.

Dans ce cas, n'est pas un gestionnaire une instance d'un employé?

Les classes Manager et Employee doivent toutes deux avoir un membre de données reportsTo qui est également de type Employee. La seule différence que je peux voir pour le moment est qu'un objet Manager a maintenant une collection d'objets Employee qui sont leurs propres directReports. Cela devrait probablement être implémenté comme un pointeur vers un conteneur d'objets Employee.

Je ne peux pas penser à une spécialisation dans le comportement qui nécessite de séparer un objet employé d'un objet Manager. Hmmm, peut-être rendre la personne de la classe de base qui contient des détails de contact dedans.

Éditez: Désolé, de votre commentaire je suppose que je n'étais pas assez clair. Ce que j'ai décrit ne conduit pas à deux classes distinctes dérivées directement de votre classe Contact, de sorte que vous devez changer une instance d'un employé en Manager pendant l'exécution, ce qui était votre question initiale. C'est-à-dire, je ne pense pas que vous devriez avoir deux classes dérivées, un employé et un gestionnaire, héritant directement de votre classe Contact.

Les cas de types de personnes employés par une entreprise ne sont-ils pas tous deux présents? Pourquoi distinguer entre un manager et un employé? Un employé n'est-il plus un employé s'il devient gestionnaire? Avoir deux classes dérivées, un gestionnaire et un employé, est complètement faux IMHO. Avez-vous essayé de casser les choses en termes de relations «isa» et «a». Ensuite, vous pouvez voir que votre structure de base est fausse.

Pour dire un employé "isa" Le contact n'a tout simplement aucun sens. Plus probablement, une personne "isa" et une personne "a" un ensemble de coordonnées.

Peut-être dériver la classe Manager en tant que spécialisation d'un employé? Un employé "isa" Personne. Un Manager "isa" Employé qui "isa" Person.

HTH

acclamations,

+0

Je suis désolé cela n'aide pas vraiment du tout. Vous dites que je représente incorrectement un gestionnaire, puis que je décris exactement ce que je proposais. –

+0

Désolé. Vous décrivez toujours ce que j'ai déjà. un héritage de Contact -> Employé -> Manager. La différence sémantique entre une personne et un contact est pertinente. La question est donnée cet héritage, est-ce correct de convertir un employé en une sous-classe de l'employé (Manager). –

2

Oui, il est valide.En ce qui concerne la mise en œuvre, vous pouvez utiliser:

  • Méthode statique sur le Gestionnaire: public static Manager Promote(Employee employee) { ... }
  • constructeur spécialisé sur le Gestionnaire
  • usine ou classe de service

Je pense que l'une de ces approches serait une bonne Solution. Personnellement, j'aime la solution de constructeur spécialisé car elle représente bien le monde réel: Vous créez un nouveau gestionnaire à partir d'un employé existant.

+1

Ne pas oublier Employee Demote (Manager manager) et Employee Hire (Contact contact) et Manager HireAsManager (Contact contact). –

0

Le contact est un attribut de Employee. Le travailleur (votre employé) est un rôle, le gestionnaire est un rôle. Le travailleur et le manager sont tous deux des employés, mais ont des rôles. Le rôle est une relation IS IN, Employee est une relation AM A et Contact est une relation HAS A. Employé A UN Contact (relation 1-1) Un contact par employé (1-M s'ils ont deux téléphones etc mais je m'écarte) Employé EST EN Rôle (relation MM) Nombreux employés Nombreux rôles Employé A (M-1 relatiohship) - Beaucoup d'employés, tous de type employé.

Vous changez donc de rôle.

Questions connexes