Skip to content

Instantly share code, notes, and snippets.

@aleixmorgadas
Last active June 6, 2024 14:10
Show Gist options
  • Save aleixmorgadas/cb1322d80e600115dd657d47cd767135 to your computer and use it in GitHub Desktop.
Save aleixmorgadas/cb1322d80e600115dd657d47cd767135 to your computer and use it in GitHub Desktop.

Invariantes vs Reglas de negocio

A partir de esta conversación escribo este Gist.

Posible caso

Tenemos un almacen que tiene un stock por producto.

Regla de negocio:

  • No podemos vender un producto que no tenemos stock.

En este caso podríamos pensar que esto es una invariante de stock, no puede existir un stock negativo. Por lo que creamos el concepto:

class Stock {
  constructor(private readonly productId: string,
              private readonly stock: number) {
    if (this.stock < 0) throw new Error('stock cannot be negative');            
  }              
}

Hemos creado una invariante en un objeto de dominio. Esto es muy común en DDD de intentar representar las invariantes a nivel de Value Object, Entity, o Aggregate.

Pero, ¿realmente representa el dominio?

No. El concepto de Stock puede pasar muchas cosas:

  • Se ha perdido en el almacen el articulo.
  • Se ha roto y no se había reportado.
  • Dos personas han comprado el mismo articulo a la vez.
  • Que entre se ha hecho el pedido y se ha confirmado se ha queado sin stock.

Hay un montón de casos que hacen que un stock pueda ser negativo temporalmente, de ahí la consistencia eventual.

Lo que dice la regla de negocio es que en el momento de compra queremos que el stock sea positivo. Por lo que lo que podemos hacer es tener una regla de negocio que sea en el domain service estilo:

Dream code :pointdown:

class OrderService {
  placeOrder(order) {
     const stockForProduct = stock.for(order.product);
     if (stockForProduct < 0) throw new Error('stock cannot be negative'); 
  }
}

En el segundo caso, hemos implementado la regla de negocio pero permitiendo que el stock sea negativo para poder implementar entonces esa logica de negocio para esos casos. Estilo:

  • Si stock es menor que 0, entonces pedir con urgencia a tales proveedores y entregarlo con máxima priodidad y dar un vale de regalo por las molestias.

En el primer caso, el objeto Stock no puede representar stock negativo porque es a nivel de invariante de objeto de dominio. En el segundo si que permitimos esa representación del objeto y podemos modelar el dominio de forma menos rigida.

@K4L1Ma
Copy link

K4L1Ma commented Jun 5, 2024

Handling stock reservations in high-concurrency environments requires careful architectural considerations. Amazon’s approach involves using message queues to process reservations sequentially, which effectively prevents race conditions. This, combined with optimistic locking, ensures data integrity and efficiently manages concurrent updates, allowing for scalable, reliable stock management.

Ensuring stock levels do not go negative is invariant, as negative stock would indicate a fundamental system error or these IRL edge cases being mentioned. Strategies for managing stock shortages, like checking nearby warehouses or offering alternatives, are business rules that enhance the system’s robustness and user experience.

@aleixmorgadas
Copy link
Author

Handling stock reservations in high-concurrency environments requires careful architectural considerations. Amazon’s approach involves using message queues to process reservations sequentially, which effectively prevents race conditions. This, combined with optimistic locking, ensures data integrity and efficiently manages concurrent updates, allowing for scalable, reliable stock management.

Ensuring stock levels do not go negative is invariant, as negative stock would indicate a fundamental system error or these IRL edge cases being mentioned. Strategies for managing stock shortages, like checking nearby warehouses or offering alternatives, are business rules that enhance the system’s robustness and user experience.

Lo bueno es como Amazon ha llegado a este sistema a lo largo de muchos años de aprendizaje. Lo importante de la discusión es como crear sistemas que permitan el aprendizaje, no tanto el caso de uso que me he inventado.

Justamente Amazon tiene casi 30 años de experiencia, por lo que lo interesante es como tomaron las decisiones al principio y fueron adaptando el software según aprendían. Me imagino que su primer black friday llevo tantos aprendizajes que repensaron muchos dominios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment