2021年4月9日星期五

DDD - Who has the responsbility of aggregate “deletion”?

Suppose we have a system that contains only three aggregates Employee, Organization and QueueNode. Each has it's own behaviors and boundary so they cannot be merged into one aggregate.

So now I have the requirement

Authorized employees should be able to delete queues, keeping a log of when and who did it.

What would be your solution to tackle this problem ? I will discuss my findings in the following.

Option 1 Using a domain service

class EmployeeDeleteQueueNodeService{      private QueueNodeRepository nodeRepo; // This will be injected in the constructor        void execute(Employee employee, QueueNode node){          node.raiseEvent(new QueueNodeDeleted(employee, node));          this.nodeRepo.delete(node);      }  }  

And then inject this service to the application service carrying out the use case of deleting the QueueNode.

Option 2 Injecting the QueueNodeRepository to a method of the Employee aggregate.

class Employee{      /// Constructor, unrelated business methods        void deleteQueueNode(QueueNode node, QueueNodeRepository nodeRepository){          node.raiseEvent(new QueueNodeDeleted(this, node));          nodeRepository.delete(node);      }  }  

This creates more verbose code which is always better. My only concern about this is that I'm passing the repository to the Employee method which seems to have some debate about, personally I like that approach.

Option 3 Same as the above but execute the deletion after the event fires

class Employee{      /// Constructor, unrelated business methods        void deleteQueueNode(QueueNode node, QueueNodeRepository nodeRepository){          node.raiseEvent(new QueueNodeDeleted(this, node));      }  }    // Somewhere else in the Application layer  class QueueNodeDeletionListener {      private QueueNodeRepository nodeRepo; // This will be injected in the constructor        void notify(QueueNodeDeleted event){           this.nodeRepo.delete(event.getQueueNode());      }  }  

I think the "strict" DDD approach would be this especially with event sourcing (which I'm not using), however to me it feels wrong for the method inside the Employee to only raise an event on another aggregate (may be totally wrong, this is just a gut feeling).

If this is the correct solution, where should the event listener live ? should it be registered in the application layer and notified after the first use case is carried out or should both the event publishing and deletion be carried out in one transaction (a Domain layer listener) ? Let me know what you think.

Also I've read from multiple sources that usually the concept of "Delete" is not much present in the business model, however in my specific case it is.

https://stackoverflow.com/questions/67030444/ddd-who-has-the-responsbility-of-aggregate-deletion April 10, 2021 at 11:08AM

没有评论:

发表评论