问题描述
我有一种方案,当用户请求删除时,可以根据某些逻辑将给定实体标记为软删除或硬删除。
从DDD范式着手解决这个问题,我看到了一些问题:-DDD建议对所有与持久性相关的东西都使用Repository对象,其中域层仅定义了此类repo接口(包含典型的方法(例如存储,删除,查找),以及包含实际实现的基础架构层。鉴于此,对于我这里的问题,决定是否进行软删除的逻辑属于域层,如何以这样的方式将逻辑包含在域层中,即确保其他任何删除请求的安全性
层实际上是通过此逻辑进行引导的,然后才真正在RepoImpl上调用删除操作,该操作实际上将实体从基础存储区中删除了。即使我的域服务具有 void removeEntity(Entity ent)
之类的方法,我也必须在我的回购接口上有一个名为<$ c $的公共方法。 c> void remove(Entity ent)无法达到目的,因为我不能强制始终调用服务层的 removeEntity
而不是 remove ,RepoImpl需要有一个remove方法来实现实体的删除。
建议的解决方案
===============
我有一个看起来很虚构的想法,假设Repo接口有一个抽象实现,该实现提供了最终的 public void remove(Entity ent)
,抽象实现可以做到这一点确定其软删除还是硬删除的逻辑。如果对其进行软删除,则实际上是对设置了适当标志的实体进行了更新,因此它将调用 this.store(ent)
,否则将实体包装为 DeleteEvent
类
公共类DeleteEvent< T> {
//为其参数化实体
私人帐篷;
DeleteEvent(T ent){
this.entity = ent;
}
public T getEntity(){
返回this.entity;
}
}
请注意非公共包访问构造函数对象该类只能在域层内构造,因此RepoImpl上的另一个remove方法是 void removeFromStore(DeleteEvent evt)
RepoImpl从此密封程序/持有者获取实体并实现清除过程。
尽管看起来可以正常工作/古怪,还是有一种更干净的方法来实现相同的目的?
您的主要问题是这里缺乏普遍使用的语言。软删除和硬删除不是领域术语,而是技术术语。您需要做的第一件事是在技术性删除操作周围的用例中重新考虑您的语言。删除到底是什么意思?我想说,您需要一个取消,撤消,到期,挂起,禁止,阻止,完成等功能。以状态来考虑,您将域模型用于CRUD操作。 b
$ b
然后您的问题的答案是:永远不要硬删除。
更多阅读:
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 ??
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/
这篇关于DDD中的软删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!