Pregunta

Supongamos que tenemos una entidad raíz agregado el tipo de pedido que se relaciona clientes y líneas de pedidos. Cuando pienso en una entidad orden que es más natural para conceptualizar como no estar definido sin un Id. Una orden sin una identificación parece estar mejor representada como una solicitud de pedido de un pedido.

Para añadir una orden a un repositorio, por lo general la gente vea una instancia del orden sin la identificación y luego tener el repositorio completa del objeto:

class OrderRepository
{
    void Add(Order order)
    {
        // Insert order into db and populate Id of new order
    }
}

Lo que me gusta de este enfoque es que va a agregar una instancia de pedido a un OrderRepository. Eso tiene mucho sentido. Sin embargo, la instancia de orden no tiene una identificación, y al alcance del consumidor del repositorio, que todavía no tiene sentido para mí que una orden no tiene una identificación. Podría definir un OrderRequest a ser una instancia de orden y añadir que al repositorio, pero que se siente como una manzana que deriva de una naranja y luego agregarlo a una lista de naranjas.

Por otra parte, también he visto este enfoque:

class OrderRepository
{
    Order AddOrder(Customer customer)
        // It might be better to call this CreateOrder
    {
        // Insert record into db and return a new instance of Order
    }
}

Lo que me gusta de este enfoque es que una orden es indefinido y sin una identificación. El repositorio puede crear el registro de base de datos y reunir todos los campos requeridos antes de crear y devolver una instancia de un objeto. Lo que huele aquí es el hecho de que en realidad nunca agrega una instancia de un objeto en el repositorio.

De cualquier manera las obras, por lo que mi pregunta es:? ¿Tengo que vivir con una de estas dos interpretaciones, o hay una mejor práctica para modelar la inserción

He encontrado esta respuesta que es similar, pero para objetos de valor: ¿cómo debo añadir un objeto en una colección mantenida por agregada raíz . Cuando se trata de un objeto de valor que no hay confusión, pero mi pregunta preocupaciones una entidad con identiy derivado de una fuente externa (base de datos generada-Auto Id).

¿Fue útil?

Solución

Me gustaría empezar por descartar el segundo enfoque. No sólo lo hace parecer contrario a la intuición, sino que viola varios principios de diseño bueno, como Separación de comandos de consulta y la principio de mínima sorpresa .

Las opciones restantes dependen de la lógica de dominio. Si los dictados lógica de dominio que una orden sin un ID no tiene sentido, el ID es un invariante requerido de Orden, y hay que modelar así:

public class Order
{
    private readonly int id;

    public Order(int id)
    {
        // consider a Guard Clause here if you have constraints on the ID
        this.id = id;
    }
}

Tenga en cuenta que al marcar el campo id como readonly hemos hecho un invariante. No hay manera de que podamos cambiarlo para una instancia de orden dado. Esto encaja perfectamente con Domain-Driven Design 's Entidad patrón.

Puede valer más la lógica de dominio, poniendo una cláusula de Guardia en el constructor para evitar que el ID de ser negativo o cero.

A estas alturas ya se está preguntando probablemente cómo esto posiblemente trabajo con identificadores generados automáticamente a partir de una base de datos. Bueno, no lo hace.

No hay una buena manera de asegurarse de que el ID suministrada no está ya en uso.

que te deja con dos opciones:

  • Cambiar el ID de un GUID. Esto permite que cualquier persona que llama para el suministro de un identificador único para un nuevo orden. Sin embargo, esto requiere el uso de GUID como claves de bases de datos también.
  • Cambiar la API para que la creación de un nuevo orden no toma un objeto Orden, sino más bien un OrderRequest como usted sugiere -. El OrderRequest podría ser casi idéntica a la clase de pedido, menos el ID

En muchos casos, la creación de un nuevo orden es una operación de negocio que necesita ejemplos específicos, en cualquier caso, por lo que veo ningún problema para hacer esta distinción. Aunque Orden y OrderRequest pueden ser semánticamente muy similar, que ni siquiera tienen que estar relacionados en la jerarquía de tipos.

Me podría incluso ir tan lejos como para decir que no debe estar relacionado, porque OrderRequest es un Valor de objetos mientras que la Orden es un Entidad .

Si se adopta este enfoque, el método AddOrder debe devolver una instancia de pedido (o al menos la identificación), porque de lo contrario no podemos conocer el ID de la orden que acabamos de crear. Esto nos lleva de nuevo a CQS violación por lo que tiendo a prefieren GUID para ID de Entidad .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top