1

Ive been tossing this around in my head for awhile. But I'm working on a project that consists of an Order, that has a OrderStatus. There is quite a bit of logic that revolves around the status and changing of it.

I've got my fake order class below and I'm curious on the possible ways of implementing this logic - I've run into issues because when calling 'Approve' for example, 'Approve' doesn't know what the actual 'OrderStatusId' for the corresponding status is, and I'm not sure the correct way of relaying that information or doing it some other way entirely.

I'm curious how others here have implemented something similar. Currently I'm doing it in a domain Service instead that just has an 'Approve' and looks up the correct status. But that seems to be taking away a lot of the logic from the domain model.

Order
{
   Guid Id
   Guid OrderStatusId
   
    void Approve();// What is the correct OrderStatusId to set? Would need db lookup
    void Deny();
    void WithDraw();
 }

Would it make sense to pass a domain service to these calls like so:

  Approve(IOrderStatusResolver resolver)
  {
    var approvalStatus = resolver.ResolveStatus(OrderStatus.Approved);
    this.OrderStatusId =approvalStatus.Id
    //More logic etc.
  }

Thanks!

9
  • At a first glance, this looks fine to me. But to decide if there is more logic which can be refactored from the OrderStatusResolver into the Order, or maybe into a domain object of its own, one has to know more details about ResolveStatus.
    – Doc Brown
    Commented Oct 10, 2023 at 5:17
  • 1
    Why is OrderStatus an entity and not a Value Object?
    – Rik D
    Commented Oct 10, 2023 at 5:43
  • @Rikd can you give an example on how I could do that, currently it has its own Id and table, which I didn't think made a good ValueObject. It's a FK to the Order stats table Commented Oct 10, 2023 at 7:13
  • @DocBrown The resolve status in this instance above is just using the domain service to fetch the OrderStatus Entity that is the 'Approve' status. The rest of the approval process would happen in the Order . Commented Oct 10, 2023 at 12:55
  • @KryptoBeard Try to model your domain without the constraints of a relational database in mind. Focus on behavior, not data. Btw. why do you store this status in a separate table and not simply as a string in the Order table?
    – Rik D
    Commented Oct 10, 2023 at 13:32

2 Answers 2

1

Having the status handling separate from the actual order is the way for you to go.

A status is always something that is related to some process. But the responsibility of the order is to say what items are ordered and by whom (and possibly other things). The status of the order is the location of that order in said process and so stems from a completely different responsibility. If the order needs to be presented with a status than this is really just a presentation issue and not one that must be dealt with in the core business logic. It should normally also not be possible to set an order state directly. The state is produced by providing the state machine of the order process with inputs and let that state machine figure out what the state of the order is.

3
  • I have a hard time time at least with the way order is used to say that the order status is not part of the core business logic, when almost everything that a order does depends on the order status. Commented Oct 10, 2023 at 12:52
  • 1
    @KryptoBeard Well, I probably should better have said "dealt with in the order logic" instead of "dealt with in the core business logic". But the point is that there is something "around" the order that handles the transition to different states. I think that is what you need to model in your domain. In the DDD book Eric Evans once talked about an application example of shipping cargo. But in the course of the project it came out that cargo itself was not the most important thing the application is about but the liabilities for cargo. So maybe you are in a somewhat similiar situation. Commented Oct 10, 2023 at 13:13
  • Thanks for the info. I'm just stuck how to gracefully handle this. Currently using a Domain service to initiate status transfers, but wasn't sure if that was the right use Commented Oct 10, 2023 at 13:21
1

Having an OrderStatusId on the object is a symptom of database first design and should be avoided unless you have some dynamically editable set of states

The easiest solution is simply to use an enum

I see from your comment that you do indeed have an editable list of states. Which begs so many questions. (What happens when they delete "Approved" from the list of order states?)

In this case presumably "Approving" an order is in of itself a user configurable action, and you can give them a drop down of states to choose from, saving the ID to be used with the "Approval" action

3
  • They won't be deleting states, but rename them for the front end display. Also could add additional statuses later that would then have to be addressed in code as well. Does DDD modeling just not work with FK columns? Seems crazy to be me everything is a free for all string or int. Seems easy to allow bad data and bad maintenance practice if things change Commented Oct 10, 2023 at 17:41
  • No matter, don't have a choice though. Trying to work with what I've got and was just looking for options Commented Oct 10, 2023 at 17:52
  • you can still do relational db if you like. just don't carry it through to your model. I'd just have an enum. If they really want to rename then you can have a seperate map for the front end which is never touched by the logic
    – Ewan
    Commented Oct 10, 2023 at 20:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.