How to simulate a warehouse application using DDD / CQRS / ES?

We want to simulate a warehouse application. Suppose we have identified the following real world objects:

  • Articles (things stored in a warehouse)
  • Palettes (where the articles are located)
  • Compartment (spaces in racks where palettes are stored)

The following restrictions apply:

  • The palette is in one compartment
  • The compartment can contain zero or one palette

To begin with, we have one operation:

  • Move (moves the palette from the current slot to another).

Of course, this is very simplistic.

How should this be modeled?

Stockitem can be a value object that I think. One solution would be to model the entire warehouse as an aggregate with palette and compartment elements. The move operation can be implemented without any problems in this case regarding its constraints (invariants). But this approach has obvious disadvantages. The event log for this unit will grow indefinitely. The two move operations cannot be performed in parallel due to aggregated versioning etc. And from ddd's point of view, this seems to me to be wrong.

Another approach would be to make each palette and each compartment its own unit. But how will the move operation be implemented?

Problem 1: Who is downloading the referenced aggregates?

I think he should stick to the palette. The palette can refer to the compartment in which it is located (its unit). But how is this link implemented (CQRS / ES)? The move command commander will obviously download the palette aggregate from the palette repository and call the move method on it. Who loads the said compartment? Who's loading the compartment, needs to be moved? I read that aggregates should not access repositories. Should the command stick load both bays? Should bays be assigned to the move method as parameters? Or should the command stick set the current compartment to the palette and give the target compartment as a parameter?

Objective 2 and 3: Constraints and bidirectional communication between units

How about restrictions? To check if a target slot is empty, the slot needs to know the palette that is stored in it. This will be a bi-directional association and should be avoided. And since they are different aggregates, they cannot be updated in a single transaction. Does the palette have a fire for a domain event to tell the coupe that it will move towards it? Will this be implemented as an undo saga? What if two movements conflict, one wins, but the falling palette cannot be brought back because the old compartment is full in the meantime?

This is all very difficult for me with regard to a really simple problem.

In books and examples, it seems so clear. But if I try to use it, I seem to be wrong.

Can anyone guide me in the right direction?

+3


source to share


2 answers


Problem 1

I think you need to do transactional analysis in addition to business analysis.

If your domain is very compatible (which is why DDD is recommended), how often does it jump to a particular compartment? Would it make sense if the Move operation occurred on a transaction that spans aggregates 2 Compartment

(source and target)? Or will there be enough consistency where the source pod will signal the world about the event that Palette left, and the target pod will somehow be informed asynchronously that the Palette is connecting it?

A palette floating "in limbo" for a short amount of time can be perfectly acceptable, something you need to ask a domain expert about.



Problem 2

Bidirectional communication is not the only solution. You can set PaletteRepository

an ID X for all palettes that have a compass. Alternatively, a branch can (should) have a list of palette IDs rather than a full reference to them.

Overall I think you should take a look first if there is a business answer / answer to all the design questions you ask yourself. The domain expert will usually have an educated opinion on whether the final sequence is realistic or whether immediate consistency is required, what should happen in the event of a conflict, etc.

+1


source


You should just start out with an object modeling behavior and don't think about aggregates and value objects at all. After you have modeled the required behavior, you will know what objects, aggregates, roots, and value objects are.



In Vaughn Vernon's explanations, he makes it clear that you need to figure out the details of what you need before you can make those decisions.

+1


source







All Articles