2010-05-18 17 views
67

Estoy tratando de comprender los Modelos de Dominio Anemico y por qué son supuestamente un antipatrón.Evitando el modelo de dominio anémico - un ejemplo real

Aquí hay un ejemplo del mundo real.

que tienen una clase de empleados, que tiene un montón de propiedades - nombre, sexo, nombre de usuario, etc.

public class Employee 
{ 
    public string Name { get; set; } 
    public string Gender { get; set; } 
    public string Username { get; set; } 
    // Etc.. mostly getters and setters 
} 

A continuación tenemos un sistema que implica la rotación de las llamadas telefónicas entrantes y consultas sitio web (conocidos como 'pistas ') uniformemente entre el personal de ventas. Este sistema es bastante complejo ya que involucra consultas de rutina, verificación de vacaciones, preferencias de los empleados, etc. Por lo tanto, este sistema está actualmente separado en un servicio: EmployeeLeadRotationService.

public class EmployeeLeadRotationService : IEmployeeLeadRotationService 
{ 
    private IEmployeeRepository _employeeRepository; 
    // ...plus lots of other injected repositories and services 

    public void SelectEmployee(ILead lead) 
    { 
     // Etc. lots of complex logic 
    } 
} 

A continuación, en la parte trasera de nuestro formulario de consulta web que tienen un código como éste:

public void SubmitForm() 
{ 
    var lead = CreateLeadFromFormInput(); 

    var selectedEmployee = Kernel.Get<IEmployeeLeadRotationService>() 
           .SelectEmployee(lead); 

    Response.Write(employee.Name + " will handle your enquiry. Thanks."); 
} 

Realmente no encuentro muchos problemas con este enfoque, pero se supone que esto es algo que debería funcionar gritando porque es Anemic Domain Model.

Pero para mí no está claro a dónde debe ir la lógica del servicio de rotación principal. ¿Debería ir a la cabeza? ¿Debería ir en el empleado?

¿Qué pasa con todos los repositorios inyectados, etc. que requiere el servicio de rotación? ¿Cómo se inyectarían en el empleado, dado que la mayoría de las veces al tratar con un empleado no necesitamos ninguno de estos repositorios?

+0

+1 gran pregunta! – mdma

+0

Entonces, ¿cómo se ve un 'ILead', si no es obvio poner .SelectEmployee() en él? –

+0

Bueno, el plomo en este caso es una consulta web, por lo que tendrá una propiedad de comentarios, etc. Pero también tenemos consultas telefónicas, aplicaciones, presupuestos, etc. que son ligeramente diferentes. La interfaz de ILead tendría propiedades como LocationOfLead, TimeOfLead, etc. – cbp

Respuesta

49

En este caso, esto no constituye un modelo de dominio anémico. Un modelo de dominio anémico es specifically about validating and transforming the objects. Así que un ejemplo de esto sería si una función externa realmente cambió el estado de los empleados o actualizó sus detalles.

lo que está sucediendo en este caso es que está tomando todos los empleados y haciendo una selección de uno de ellos en función de su información. Está bien tener un objeto separado que examine a los demás y tome decisiones con respecto a lo que encuentre. NO es correcto tener un objeto que se utiliza para hacer la transición de un objeto de un estado a otro.

Un ejemplo de un modelo de dominio anémico en su caso sería contar con un método externo

updateHours(Employee emp) // updates the working hours for the employee 

que toma un objeto Employee y actualiza sus horas de trabajo para la semana, asegurándose de que las banderas se plantean si el las horas exceden un cierto límite. El problema con esto es que si solo tiene objetos Employee, entonces no tiene conocimiento de cómo modificar sus horas dentro de las restricciones correctas.En este caso, la forma de manejarlo sería mover el método updateHours a la clase Employee. Ese es el quid del patrón anti Patrón Anemic.

+0

Pero, ¿y si el empleado es un objeto persistente para la base de datos? ¿Por qué debería poner un método allí? La misma pregunta es válida para los DTO donde no se ponen métodos dentro. ¿Dónde colocarías el método updateHours? – Pascal

+0

'updateHours' pertenece a la clase Employee. Debería pasarle los datos necesarios para actualizar las horas, por ejemplo, la tarea que se completó. Los objetos de colaborador también están bien, pero preferiblemente no hay servicios. – MauganRa

29

Creo que su diseño está bien aquí. Como saben, el anti-patrón del modelo de dominio anémico es una reacción en contra de la tendencia de evitar cualquier comportamiento codificado en objetos de dominio. Pero, por el contrario, no significa todo el comportamiento relacionado con un objeto de dominio debe ser encapsulado por ese objeto.

Como regla general, el comportamiento que está intrínsecamente vinculado al objeto de dominio y se define por completo en términos de esa instancia de objeto de dominio se puede incluir en el objeto de dominio. De lo contrario, para mantener las responsabilidades claras, lo mejor es exponerlo externamente en un colaborador/servicio como lo ha hecho.

+5

exactamente. Se trata de un módulo externo (LeadQueueManager o lo que sea) con una gran cantidad de lógica interna; este no es en absoluto un modelo de dominio anémico. ¿Qué sabe un empleado sobre la programación de la cola de llamadas? Nada;) – TomTom

13

Todo está en tu cabeza: considera que el servicio de rotación forma parte del modelo de dominio y el problema se disuelve.

La rotación necesita mantener la información sobre muchos empleados, por lo que no pertenece a ningún cliente potencial, ni a ningún objeto de empleado individual. Lo hace para merecer ser un objeto de dominio en sí mismo.

Simplemente renombrar "RotationService" a algo así como "Organization.UserSupportDepartment" lo hace obvio.

0

Si su modelo de dominio contiene solo roles y cosas, no actividades como comportamiento, entonces es anémico. Sin embargo, estoy hablando de comportamiento con respecto a un modelo no un objeto . Hablo de la diferencia entre ellos en otra respuesta ... https://stackoverflow.com/a/31780937/116442

Desde su pregunta, romper mis primeras reglas de modelado de análisis de dos dominios: -

  1. comportamiento modelado como Actividades (grabadas) están en el corazón de un modelo de dominio. Agréguelos primero.
  2. Modele las actividades de dominio como Clases, no como métodos.

Agregaría una actividad "Consulta" al modelo. Con él, el modelo tiene un comportamiento, y puede combinar y trabajar como un grupo de objetos sin un controlador externo o secuencia de comandos.

EnquiryHandlerModel

Cuestiones relacionadas