我是Java的新手并加入了一个利用DDD模式的项目(据称)。我来自一个强大的python背景,并且相当肛门关于单元测试驱动设计。也就是说,迁移到Java的挑战之一是服务层的可测试性。
我们的类似REST的项目堆栈如下所示:
ServiceHandlers
处理请求/响应等,并调用IService
的特定实现(例如DocumentService
)DocumentService
- 使用makeOwner(session, user, doc)
目前,DocumentService
之类的东西通过guice注入了存储库依赖项。在像DocumentService.makeOwner
这样的公共方法中,我们希望确保会话用户是管理员以及检查目标用户是否已经是所有者(利用注入的存储库)。这导致一些欺骗代码 - 一个用于解决用户并确保成员资格,权限等的用户。为了消除这个冗余代码,我想做一种超级简单的isOwner(user, doc)
调用,我可以简洁地模拟out for各种测试场景(例如在用户无法解决时抛出异常等)。这是我的谷歌搜索让我失望的地方。
如果我将它与DocumentService
放在同一个类中,我可以在同一个类中测试makeOwner
时模拟它(由于Mockito限制),即使它有点像它应该去(选项1)。
如果我把它放在像DocumentHelpers
这样的较低级别中,感觉有点滑稽,但我可以很容易地模仿出来。此外,DocumentHelpers也需要注入的存储库,这对guice很好。 (选项2)
我应该补充一点,在我们的婴儿代码库中有许多这种性质的点目前是不可测试的,因为方法在上层ServiceHandler类没有使用的同一* Service类中非静态地调用类似helper的方法。但是,在这个阶段,我无法判断这是不好的设计还是没问题。
所以我问更有经验的Java开发人员:
要添加的3位:
感谢任何指导。
答案 0 :(得分:0)
启动操作的用户必须是管理员,看起来像应用程序级访问控制问题。 DDD对你应该如何做到这一点没有太多意见。出于可测试性和关注点分离的目的,有一种单独的非静态类可能比同一服务中的方法或静态助手更好。
检查未来的所有者是否已经是所有者(如果我理解正确的话)可能是另一种动物。它可能是您域中的不变量。如果是这样,首选方法是依靠Aggregate来强制执行该规则。但是,从您的描述中不清楚Document
是否是聚合,以及它或其他聚合是否包含告知用户是否为所有者所需的数据。
或者,您可以在应用程序层级别验证规则,但这意味着如果状态更改由该应用程序层之外的其他内容触发,则您的域模型可能会不一致。