design-patterns - Active Record 模式、Repository 模式和可测试性(java 中)

标签 design-patterns activerecord domain-driven-design repository-pattern ddd-repositories

以下旨在充分利用事件记录模式和存储库模式的方法有什么缺点(例如在可测试性方面)?

每个持久化对象都暴露了save()和delete()方法,但没有静态方法来加载自身,或者加载类似对象的列表:从上层加载是通过直接调用存储库来完成的,以避免静态方法持久对象。

“save()”和“delete()”方法只是外观,它们被委托(delegate)给存储库。

这种方法真的需要考虑可测试性吗?即使使用纯 Active Record 方法:是否存在数据库逻辑仅代表整个业务逻辑的一小部分的信息系统,并且模拟数据库访问会很有趣?

编辑:这种方法需要持久对象从实现“save()”和“delete()”的AbstractPersistentObject继承,并且它会阻止业务继承,但我读到最好避免业务继承,并用组合代替它,所以它可能是一个优点,而不是一个缺点......?

编辑2:也许这篇文章会更好地解释我正在尝试解决的问题:http://moleseyhill.com/blog/2009/07/13/active-record-verses-repository/

最佳答案

有两件事引起了一些担忧。第一个是这句话(强调我的):

[...] are there information systems where database logic represents only a small part of the whole business logic, and where it would be interesting to mock the database access?

您是否将业务逻辑放入数据库中?如果是这样:不要这样做,它会使模拟您的数据库非常变得困难。您必须将所有业务逻辑从数据库复制(并维护!)到您的模拟,否则您的测试毫无用处。

但是您如何知道模拟是否正确实现了业务逻辑?您可以为模拟编写单元测试,或者重用数据库的单元测试(您确实有它们,对吧?),但这是我不惜一切代价尝试避免的方法!让我再说一遍:永远不要(必须)为你的模拟编写单元测试。如果您发现自己处于这种情况,请退后几步并检查您的设计,因为有些地方非常错误。

将业务逻辑放入数据库只会在模型和数据库之间产生不必要的耦合,并使测试层变得非常复杂。关注点分离是这里的关键:模型仅关注业务逻辑,数据库仅关注持久性,没有其他。

这让我想到了下一个问题:为什么在域模型上需要与持久性相关的 save()delete() 方法? 持久性不属于域模型。

我知道,您说过这些方法将委托(delegate)给存储库,因此域模型(希望)不包含实际的持久性逻辑。但它如何知道应该委托(delegate)给哪个存储库?

如果您在 save() 方法中调用服务定位器,则无法将实体保存到多个存储库。您还向调用者隐藏了对存储库的依赖关系,我认为这是一件坏事。

要解决这些问题,您可以将存储库实例传递给 save() 方法,如下所示:

public class Foo extends AbstractPersistentObject {
    public void saveTo(IFooRepository repository) {
        repository.save(this);
    }
}

但是这样的方法意味着调用者已经有一个存储库实例,因此他不妨直接在存储库上调用 save() 方法。域模型上的任何持久性方法都将过时。

也许我把你的问题过于简单化了。你想达到什么目的?您只需要 entity.save() 语法,还是想解决更大的问题?

关于design-patterns - Active Record 模式、Repository 模式和可测试性(java 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5677518/

相关文章:

winforms - mvp模式中winforms之间的通信

mysql - 在连接查询中返回不同的记录 - Rails 4

design-patterns - 在 DDD 中在哪里实现聚合级别的权限?

asp.net-core - DDD 通过多层过滤器

design-patterns - 使用哪种设计模式来制作披萨

WPF 设计问题(自定义控件或 mvvm)

mysql - 数据库模式知识边界

ruby-on-rails - 从 ActiveRecord/ActiveModel JSON 输出中过滤字段(神奇!)

ruby-on-rails - 使用正则表达式的高级 Active Record 顺序

c# - 非聚合根可以保存另一个非聚合根的引用吗?