【发布时间】:2016-01-22 21:04:48
【问题描述】:
简介
我将 Dagger 2 用于使用DDD 的原则建模的项目。
我想使用Builder Pattern 创建复杂的实体,而我通常获取构建器实例的方式是使用静态工厂方法:ComplexEntity.builder()。
聚合根将获得强类型 ID,即 ComplexEntityID,这需要新实例的值生成器。现在我的模块中有一个方法:@Provides ComplexEntityID provideComplexEntityID(IdValueGenerator generator) { return new ComplexEntityID(generator.nextId(); }。
ComplexEntityBuilder 需要ComplexEntityID 的实例(或提供者)才能创建ComplexEntity。但是 Guice 和 Dagger(以及其他)的人建议不要使用静态注入,这是有充分理由的。
问题
如何使用构建器创建ComplexEntity 的实例,而不使用静态注入?也就是说,如何获取builder的实例?
坚持ComplexEntity.builder() 会很好,因为这是一个通用约定,但我认为在不使用new () 关键字的情况下使实例在静态方法中可用的唯一方法是使用静态注入。
我能想到的另一种方法是创建ComplexEntityFactory 并将builder() 方法放在那里。但是同时使用 factory 和 builder 似乎有点奇怪:
- 在需要的类中注入工厂
complexEntityFactory.builder().value1(...) .value2(...) .build();
在这种情况下推荐的方法是什么?
编辑:如果它毕竟是一个专用工厂,如果这个工厂仍然可以使用AutoFactory 或类似的东西生成,那就太好了
【问题讨论】:
-
您可以将
ComplexEntityID传递给静态工厂方法:ComplexEntity.builder(complexEntityID)。构建器的构造函数采用所需参数并不罕见。 -
我想这是一个合理的解决方案。这确实意味着无论我需要在哪里构建
ComplexEntity,我都会依赖Provider<ComplexEntityID>。 -
@jaco0646 作为 API 的使用者,您是否会发现需要
Provider<ComplexEntityID>实例的ComplexEntity.builder(ComplexEntityID id)比获取ComplexEntityFactory的实例更直观/可用,并从那里获取构建器(考虑到任何一种方法都会在整个应用程序中一致使用)? -
这取决于消费者是否知道该 ID。我不会仅出于此目的将 ID 引入 API;但如果消费者在其他地方使用该 ID,那么再次使用它会增加很少的概念开销。
-
感谢您的洞察@jaco0646。消费者会知道该 ID,但仅用于参考而不用于实例化(为新实体动态创建,或为现有实体反序列化)。我尝试了一段时间,并意识到更改名称会有所作为;我最终得到了一个
BuilderFactory,其中包含特定有界上下文的所有相关构建器。它主要用于命令,因此这在 API 中提供了一个很好的中心位置,可以从中为该上下文构建命令。例如。workspaceCommandBuilderFactory.archiveWorkspace()...build();
标签: java design-patterns dependency-injection domain-driven-design