Mi lenguaje de programación es C#. Tengo una pregunta sobre la ignorancia de la persistencia dentro de mi modelo de dominio.Persistente ignorante Capa de dominio
Supongamos que tengo una clase de persona, así:
public class Person
{
private string email;
public string Email
{
get { return email; }
set { email = value; }
}
public Person(string email)
{
this.email = email;
}
}
Ahora, dentro de mi modelo de dominio, hay una regla que no puede haber dos personas que tengan la misma dirección de correo electrónico. Por lo tanto, al crear una instancia de una nueva persona, debe validarse así como también al cambiar la propiedad del correo electrónico. Así que me preguntaba cómo resolverías esa validación dentro de tu capa de dominio ignorante de persistencia. Lo que hago actualmente es usar un patrón de fábrica para la creación de instancias de personas en el que inyecte un repositorio de personas. Allí puedo buscar a otra persona con la misma dirección de correo electrónico. De este modo:
public class PersonFactory
{
private static readonly IPersonRepository personRepository;
public Person CreateNewPerson(string email)
{
Person personWithSameMail = personRepository.GetPersonByEmail(email);
if (personWithSameMail != null)
throw new ApplicationException("Email already exists.");
return new Person(email);
}
public PersonFactory(IPersonRepository personRepository)
{
this.personRepository = personRepository;
}
}
Pero el uso de esta solución, el cheque al cambiar la dirección de correo electrónico personas (que puede ser un modelo de negocio válido) todavía no está cubierta. Además, la clase Persona todavía expone un constructor público y al pasar por alto la fábrica, las personas con direcciones de correo electrónico duplicadas todavía serían posibles.
¿Alguna solución elegeant a esto?
P.S. Para todos los datos centrados en las personas: No, no quiero para validar correos electrónicos duplicados en la capa de acceso a datos;)
ACTUALIZACIÓN:
Probablemente toda esta cuestión es obsoleta de todos modos. Verificar si hay correos electrónicos duplicados en términos del contexto de un modelo de dominio siempre requerirá "algo" que tenga en cuenta a todas las personas: una raíz. El "algo" podría ser una libreta de direcciones o todo el mundo que contiene a todas las personas con direcciones de correo electrónico. Así que tal vez estoy mezclando los programadores que necesitan soluciones técnicamente elegantes para los problemas, que existe solo por la falta de un modelo de dominio completo y bien pensado. ¿Puede ser este el caso aquí? Que no solo hay una persona con una dirección de correo electrónico flotando en el espacio (hey, el espacio sería mi raíz agregada aquí;)) solo por la diversión de la existencia. Pero si esto fuera un verdadero caso comercial como una aplicación de libreta de direcciones, la libreta de direcciones sería la raíz agregada de la persona y, por lo tanto, podría verificar todas las personas en su colección interna para asegurarse de que no haya una dirección de correo electrónico duplicada.
¿Por qué no hace el constructor interno y también verifica la dirección de correo electrónico al actualizar? Y no creo que sea una buena solución para dar un repositorio a una fábrica. La función de servicio que llama a la fábrica debe verificar si la dirección de correo electrónico ya existe. –
@WouterdeKort: No estoy de acuerdo con su comentario: (1) Hacer interno el controlador no ayuda en nada. Todavía permite la creación de usuarios con direcciones de correo duplicadas. (2) Hacer que el método que llama a la fábrica haga el control de forma efectiva elimina esa regla comercial. Ahora depende de la persona que llama para hacer cumplir esta regla. Eso es solo un diseño API muy pobre –
@DanielHilgarth Menciona explícitamente que el constructor público es un problema. Una fábrica debe construir un objeto con todas las dependencias y valores requeridos. Mezclar lógica de negocios con una fábrica es algo que llamaría mal diseño. –