La forma en que hace la pregunta (y propone dos alternativas) es como si la única preocupación es que el driverId todavía es válido en el momento en que se crea el automóvil.
Sin embargo, también debe preocuparse de que el conductor asociado con driverId no se elimine antes de que el automóvil se elimine o se le dé otro conductor (y posiblemente también que el conductor no esté asignado a otro automóvil (esto si el dominio restringe a un conductor a solo estar asociado con un automóvil)).
Sugiero que en lugar de la validación, asigne (lo que incluiría la validación de presencia). A continuación, no permitirá las eliminaciones mientras esté asignado, evitando así la condición de carrera de los datos obsoletos durante la construcción, así como el otro problema a largo plazo. (Tenga en cuenta que la asignación valida y marca, y opera atómicamente).
Por cierto, estoy de acuerdo con @PriceJones en que la asociación entre el automóvil y el conductor probablemente sea una responsabilidad separada del automóvil o del conductor. Este tipo de asociación solo crecerá en complejidad con el tiempo, porque suena como un problema de programación (conductores, automóviles, franjas horarias / ventanas, sustitutos, etc.) Incluso si es más como un problema de registro, uno puede querer un historial registros, así como registros actuales. Por lo tanto, es muy posible que merezca su propio BC completamente.
Puede proporcionar un esquema de asignación (como un conteo booleano o de referencia) dentro del BC de las entidades agregadas que se asignan, o dentro de un BC separado, por ejemplo, el responsable de hacer la asociación entre el automóvil y el conductor. Si hace lo primero, puede permitir operaciones de eliminación (válidas) emitidas para el automóvil o el conductor BC; si hace lo último, deberá evitar las eliminaciones de los BC del automóvil y el conductor y, en su lugar, enviarlos a través del programador de asociación de automóvil y conductor.
También puede dividir algunas de las responsabilidades de asignación entre BC de la siguiente manera. El coche y el conductor BC proporcionan un esquema de "asignación" que valida y establece el booleano asignado con ese BC; cuando se establece su asignación booleana, el BC impide la eliminación de las entidades correspondientes. (Y el sistema está configurado para que el BC del automóvil y el conductor solo permita la asignación y la desasignación desde el BC de la asociación del automóvil / conductor).
El BC que programa el automóvil y el conductor mantiene un calendario de conductores asociados con el automóvil durante algunos períodos de tiempo / duraciones, ahora y en el futuro, y notifica a los otros BC de la desasignación solo en el último uso de un automóvil o conductor programado.
Como una solución más radical, puede tratar a los BC de automóviles y conductores como fábricas de registros históricos solo anexables, dejando la propiedad al programador de asociación de automóvil / conductor. El automóvil BC puede generar un automóvil nuevo, completo con todos los detalles del automóvil, junto con su VIN. La propiedad del automóvil es manejada por el programador de asociación de automóvil / conductor. Incluso si se elimina una asociación de automóvil / conductor, y el automóvil en sí mismo se destruye, los registros del automóvil aún existen en el automóvil BC por definición, y podemos usar el automóvil BC para buscar datos históricos; mientras que las asociaciones / propietarios de automóviles / conductores (pasados, presentes y potencialmente futuros programados) están siendo manejados por otro BC.
Driver.delete
no debería existir Realmente nunca vi un dominio donde los agregados se destruyen. Al mantener los AR a su alrededor, nunca puede terminar con huérfanos.Podría ser útil preguntar: ¿Está seguro de que los automóviles están construidos con conductores? Nunca he oído hablar de un automóvil compuesto por un conductor en el mundo real. La razón por la cual esta pregunta es importante es porque podría indicarle la dirección de crear independientemente automóviles y conductores y luego crear algún mecanismo externo que asigne un conductor a un automóvil. Un automóvil puede existir sin una referencia del conductor y seguir siendo un automóvil válido.
Si un automóvil debe tener un conductor en su contexto, entonces es posible que desee considerar el patrón del constructor. Este patrón será responsable de garantizar que los automóviles se construyan con los conductores existentes. Las fábricas servirán autos y conductores validados independientemente, pero el constructor se asegurará de que el auto tenga la referencia que necesita antes de que lo haga.
fuente
Creo que sí. Obtener un DriverId determinado de la base de datos devuelve un conjunto vacío si no existe. Por lo tanto, verificar el resultado devuelto hace que sea innecesario preguntar si existe (y luego buscar).
DriverId
y se establece en el constructor.Car
solo necesita elDriverId
, tenga unDriver.Id
captador. Sin setter.Car
le importa si tiene unDriver
(o su ID al menos). ADriver
le importa si tiene unDriverId
. SeRepository
preocupa por la integridad de los datos y no podría importarle menos los automóviles sin conductor.DriverId
es un asunto de dominio comercial se maneja en las clases apropiadas.... sucede cuando
Repository.DriverIdExists()
hace la pregunta.Construye un objeto de dominio. Si no es un,
Driver
entonces tal vez un objetoDriverInfo
(solo unDriverId
yName
, digamos). ElDriverId
se valida en la construcción. Debe existir, y ser del tipo correcto, y cualquier otra cosa. Entonces es un problema de diseño de clase de cliente cómo tratar con un driver / driverId inexistente.Quizás a
Car
está bien sin conductor hasta que llameCar.Drive()
. En cuyo caso, elCar
objeto, por supuesto, garantiza su propio estado. No se puede conducir sinDriver
... bueno, todavía no.Claro, ten un
Car.DriverId
si lo deseas. Pero debería verse más o menos así:No esta:
Ahora se
Car
debe tratar con todos losDriverId
problemas de validez: una violación del principio de responsabilidad única; y código redundante probablemente.fuente