问题
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 ??
回答1:
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/
来源:https://stackoverflow.com/questions/11643636/soft-delete-in-ddd