soft delete in DDD
Asked Answered
L

1

0

I have a scenario where a given entity may be marked for soft delete or a hard delete based on some logic when a user requests delete.

Approaching this problem from DDD paradigm, i see some issues :- DDD proposes use of Repository object for all persistence related stuff where the domain layer just defines such repo interface (containing typical methods like store, remove, find) and the infrastucture layer containing the actual implementation. Given that, for my problem here then , the logic that decides whether to do a soft delete or not belongs domain layer, how is it possible to contain the logic in domain layer in such a way where the safety that any delete request by any other layer is channeled through this logic before coming to point of actually calling a delete on RepoImpl that actually removes the entity from underlying store ??.

  Even if I have a domain service having a method like void removeEntity(Entity ent) , the fact that I have to have a public method on my repo interface called void remove(Entity ent) defeats the purpose because I can't enforce that removeEntity of service layer is to be called always instead of remove on repo and RepoImpl needs to have a remove method to give implementation of removal of an entity.

Proposed Solution
==============
  I have this idea that looks rather contrived, let's say the Repo interface has an abstract implementation that has provides a final public void remove(Entity ent) , the abstract implementation can do this logic to determine if its a soft or hard delete. If its a soft delete its actually an update of the entity with proper flags set , so it calls this.store(ent) otherwise it wraps the entity in a DeleteEvent class

 public class DeleteEvent<T>{
   //parametrized for Entity
  private T ent;
   DeleteEvent(T ent){
     this.entity = ent;   
}

 public T getEntity(){
   return this.entity; 
}
}

Note the non-public, package access constructor, objects for this class can only be constructed from within domain layer, so the other remove method on the RepoImpl is void removeFromStore(DeleteEvent evt) RepoImpl gets entity from this sealer/holder and implements the removal process.
This although looks like can work is rather quirky/hacky, is there a cleaner way to achieve the same ??

Leek answered 25/7, 2012 at 6:5 Comment(0)
I
5

Your main problem is a lack of ubiquitous language here. Soft delete and hard delete are not domain terms but technical ones. First thing you need to do is to reconsider your language in use cases around the technical Delete action. What does Delete mean exactly? I would say you need rather a Cancel, Revoke, Expire, Suspend, Ban, Block, Finish etc. Think in terms of state you put your domain model to rather than CRUD actions.

Then the answer to your question is: never do hard delete.

More reading: http://www.udidahan.com/2009/09/01/dont-delete-just-dont/

Illsuited answered 25/7, 2012 at 10:15 Comment(3)
DDD recognizes the concept of delete isn't it ?? so when Repository interface has a method called void remove(Entity ent) what should a implemntor assume?? And since u mentioned it, how do map user CRUD actions to domain actions ?? so apparently what the user knows as delete is not delete here (in some situations). In that context the ubiquitous language doesn't extend to the user, does it??Leek
I would say remove method should set Deleted = true or something simmilar.Illsuited
If your user performs just CRUD actions do you really need DDD or just overengineering your project?Illsuited

© 2022 - 2024 — McMap. All rights reserved.