好吧,Martin Fowler 从 POEAA 一书中介绍了这种工作单元的概念。如果您想拥有自动提交系统,它会非常有效,在该系统中,您的域模型使用工作单元将自己标记为新的、脏的、已删除的或干净的。然后你只需要调用 UnitofWork.commit() 并且模型的所有更改都将被保存。以下是具有此类方法的域模型类:
public abstract class DomainModel{
protected void markNew(){
UnitOfWork.getCurrent().registerNew(this);
}
protected void markDirty(){
UnitOfWork.getCurrent().registerDirty(this);
}
protected void markRemoved(){
UnitOfWork.getCurrent().registerRemoved(this);
}
protected void markClean(){
UnitOfWork.getCurrent().registerClean(this);
}
}
使用此实现,您可以通过业务逻辑方法将域模型标记为任何保存状态:
public class Message extends DomainModel{
public void updateContent(User user, string content){
// This method update message content if the the message posted time is not longer than 24 hrs, and the user has permission to update messate content.
if(!canUpdateContent(user) && timeExpired()) throw new IllegalOperationException("An error occurred, cannot update content.");
this.content = content;
markDirty();
}
}
乍一看,它看起来很棒,因为您不必在存储库/数据映射器上手动调用插入、保存和删除方法。但是,我发现这种方法存在两个问题:
http://blog.sapiensworks.com/post/2014/06/04/Unit-Of-Work-is-the-new-Singleton.aspx/
所以你怎么看? Martin Fowler 中描述的原始工作单元模式是否违反了良好的 OO 设计原则?如果是这样,你认为它是一种反模式吗?
最佳答案
完全准确地说,没有“Martin Fowler 的工作单元实现”。在书中,他区分了将修改对象注册到 UoW 的两种类型。
来电登记其中只有调用对象知道 UoW,并且必须将(被调用)域对象标记为脏对象。据我所知,这里没有反模式或不良做法。
对象注册域对象向 UoW 注册自己的位置。这里再次有两个选项:
For this scheme to work the Unit of Work needs either to be passed to the object or to be in a well-known place. Passing the Unit of Work around is tedious but usually no problem to have it present in some kind of session object.
代码示例使用
UnitOfWork.GetCurrent()
由于紧密耦合、隐式依赖(服务定位器样式),它更接近于后一种选择,并且在今天被广泛认为是一种反模式。但是,如果选择了第一个选项,即将 UoW 传递给域对象,让我们假设一个工作单元抽象,这是不好的做法吗?从依赖管理的角度来看,显然不是。
现在仍然是持久性无知方面。我们可以说一个对象可以向另一个刚刚被编辑/创建/删除的对象发出信号,表明它是持久感知的吗?非常值得商榷。
相比之下,如果我们查看最近的领域对象实现,例如事件溯源中的实现,我们可以看到聚合 can be responsible for keeping a list of their own uncommitted changes这或多或少是相同的想法。这是否违反了持久性无知?我不这么认为。
底线 :Fowler 选择用来说明许多 UoW 可能性之一的特定代码现在显然被认为是不好的做法,但对于您指出的问题 #1 而不是真正的问题 #2,更是如此。这并没有取消他所写的其他实现的资格,也没有取消整个 UoW 模式的资格,其变化跟踪机制现在大部分时间都隐藏在第三方库魔法(阅读:ORM)中,而不是像书中的例子那样硬编码。
关于oop - Martin Fowler 的工作单元的 POEAA 实现是反模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33119379/