2009-06-16 19 views
13

En mi aplicación en este momento tengo (como en tantas otras aplicaciones) una entidad llamada Contact, que representa a cualquier persona. En su nivel más básico, esto se usa para representar contactos comerciales. Sin embargo, también se puede usar para representar a los empleados de la compañía. y también hay un par de tipos especiales de empleados (digamos que hay uno llamado Manager)Alguna vez es válido convertir un objeto de una clase base en una subclase

Estoy intentando modelar esto como una relación de herencia que tiene sentido. Los empleados tienen nombres y direcciones al igual que los contactos, así como una serie de atributos relacionados con el empleo. Los gerentes también tienen una serie de atributos específicos del administrador.

La dificultad surge cuando un empleado es ascendido a gerente. ¿Está bien convertir la clase base Employee a la clase heredada Manager? Se siente mal Supongo que lo haría con un constructor especializado en Manager.

Como complemento, NHibernate admite este tipo de comportamiento? ¿es tan simple como obtener al empleado, crear el gerente del empleado y luego guardar el administrador?

Respuesta

5

Siempre que su modelo de negocio coincida con su dominio, usted está haciendo lo correcto.

Sin embargo, suena a mí como usted debe tener algo como:

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

dentro de algún proceso de flujo de trabajo de algún tipo.

En lo que respecta a NHibernate, parece que está mezclando su lógica ORM con su dominio comercial. La promoción de un empleado a un gerente es una construcción de dominio empresarial y, como tal, pertenece a su modelo de negocio. Sin embargo, la forma en que NHibernate asigna sus empleados y sus administradores a su base de datos no tiene nada que ver con su modelo de negocio, excepto cómo mapearlos. Sin embargo, definitivamente esto no tiene nada que ver con la forma de promocionar a un empleado a un gerente.

+0

La pregunta de NHibernate fue solo para averiguar si NHibernate se quejaba de guardar un objeto como una subclase cuando se recuperaba como tipo de base. –

2

Personalmente, tengo una clase base con todas las cosas básicas y una lista de roles.
Cada función tiene sus propias propiedades y funcionalidades.
Las ventajas son dos:

  • Es fácil dar o tomar un papel de/a una persona
  • Permitirá a su gente que tienen múltiples funciones sin que tenga que hacer 'clases combinadas'

Si vas con un solo inherritance ir con inherritance pronto que el procesamiento con clases como "ManagerProgrammer", "ProgrammerStockManager", "ProgrammerSupport"

16

me gustaría ir con la composición sobre inheri tanza en este caso. Si se queda con la herencia, cambiará las clases con cada promoción o degradación y cada vez que contrata a un contacto o un empleado se va y se convierte en un contacto habitual.

Es más fácil decir que los contactos tienen roles. Puede agregar una función de administrador a un contacto para promocionarla y eliminar la función para activarla.

+1

Esto debe marcarse como la respuesta correcta – Pierreten

0

día G,

Si usted encuentra que tiene para convertir una clase derivada de un tipo a otro tipo derivado entonces que es un olor que el diseño inicial tiene problemas.

Mi intuición aquí es que está representando un objeto Manager incorrectamente.

Vuelva a los conceptos básicos y piense en términos OO donde su clase base (Contacto) contiene los elementos comunes de los objetos Empleado y Administrador. Todos los objetos derivados son solo especializaciones de la clase base.

En este caso, ¿no es un Administrador una instancia de un Empleado?

Las clases Manager y Employee deberían tener un miembro de datos de reportsTo que también sea del tipo Employee.

La única diferencia que puedo ver en este momento es que un objeto Manager ahora tiene una colección de objetos Employee que son sus propios DirectReports. Esto probablemente debería implementarse como un puntero a un contenedor de objetos Employee.

No puedo pensar en ninguna especialización en comportamiento que necesite separar un objeto Employee de un objeto Manager.

Hmmm, tal vez haga la clase base Persona que contiene detalles de contacto en ella.

Edit: Lo siento, por tu comentario, supongo que no fui lo suficientemente claro. Lo que describí no conduce a dos clases separadas, ambas derivadas directamente de su clase de contacto, por lo que debe cambiar una instancia de un empleado a un administrador durante el tiempo de ejecución, que era su pregunta original.

Es decir, no creo que deba tener dos clases derivadas, un Empleado y un Administrador, heredando directamente de su clase de Contacto.

¿No son estos ejemplos de tipos de personas que son empleados de una empresa? ¿Por qué distinguir entre un gerente y un empleado? ¿Un empleado ya no es un empleado si se convierte en un gerente?

Tener dos clases derivadas, un gerente y un empleado, es completamente incorrecto en mi humilde opinión. Has intentado dividir las cosas en términos de relaciones "isa" y "tiene". Entonces puedes ver que tu estructura básica está equivocada.

Decir un empleado "isa" El contacto simplemente no tiene sentido. Es más probable que un empleado "isa" Persona y una persona "tenga" un conjunto de detalles de contacto.

¿Tal vez derivar la clase Manager como una especialización de un empleado? Un empleado "isa" Persona. Un gerente "isa" Empleado que es "isa" Persona.

HTH

aplausos,

+0

Lo siento, esto no ayuda en absoluto. Usted dice que estoy representando a un gerente incorrectamente y luego pasa a describir exactamente lo que propongo. –

+0

Lo siento. Todavía estás describiendo lo que ya tengo. una herencia de Contacto -> Empleado -> Administrador. La diferencia semántica entre una persona y un contacto es irrelevante. La pregunta es sobre esta herencia, ¿está bien convertir un empleado en una subclase de empleado (Gerente)? –

2

sí, es válido.En lo que respecta a la aplicación se puede utilizar:

  • Método estático de Representante: public static Manager Promote(Employee employee) { ... }
  • constructora especializada en el Administrador de
  • de fábrica o de servicio de clase

creo que cualquiera de esos enfoques sería un buen solución. Personalmente, me gusta la solución de constructor especializada, ya que representa bien el mundo real: está creando un nuevo Administrador de un Empleado existente.

+1

No se olvide de Employee Demote (Gerente) y Employee Hire (Contacto de contacto) y Manager HireAsManager (Contacto de contacto). –

0

El contacto es un atributo del empleado. Trabajador (su empleado) es un rol, el gerente es un rol. El trabajador y el gerente siguen siendo empleados, pero tienen roles. El rol es una relación IS IN, Employee es una relación AM A, y Contact es una relación HAS A. Empleado TIENE un contacto (relación 1-1) Un contacto por empleado (1-M si tienen dos teléfonos, etc. pero estoy divagando) Empleado ES EN Función (relación MM) Muchos empleados muchos roles Empleado es A (M-1 relatiohship) - Muchos empleados, todos de tipo empleado.

Estás cambiando de roles.

Cuestiones relacionadas