我意识到像Morphia和Hibernate这样的持久化框架依赖于领域对象上的注释来实现它们的魔力。从某种程度上看,我觉得这是将持久化关注点插入到领域层中,这是我们应该尽力避免的。我应该通过使用外部配置文件或者将DTO与领域模型分离来避免这种情况吗?还是这种持久化和领域层之间的小漏洞通常被视为可以接受的?
我意识到像Morphia和Hibernate这样的持久化框架依赖于领域对象上的注释来实现它们的魔力。从某种程度上看,我觉得这是将持久化关注点插入到领域层中,这是我们应该尽力避免的。我应该通过使用外部配置文件或者将DTO与领域模型分离来避免这种情况吗?还是这种持久化和领域层之间的小漏洞通常被视为可以接受的?
Lead
用于持久性和一个并行的ActiveLead
,跨事务存在。最近我参与了一个相当复杂的系统开发,该系统有一个单独的持久化层,但这对于可维护性来说非常糟糕且非常麻烦。你基本上是在YAGNI原则和单一职责原则之间寻求平衡。在我看来,YAGNI是更重要的(不幸的是,也经常被忽略)。
我认为,在绝大多数情况下,如果你使用ORM,直接将领域对象持久化会更好,除非你有具体的要求需要持久化实体以不同的结构进行组织(如果它们具有完全相同的结构,则没有理由分离它们,除了纯理论争论)。
确保:总是在单独的服务/DAO层中执行实际的持久化操作(调用ORM函数)!这样,如果你发现需要它,很容易引入持久化层。
firstName
的更改,并发现其他人已更改了该对象,则需要重新加载对象以进行更改。如何将新加载和修改的对象插入回域对象树中? - David Harkness如果我已经决定使用持久化框架,我会在我的领域上使用注解;然而,如果你遵循六边形架构和TDD,XML会更加方便。如果你提前使用特定框架对领域进行注释,那么你将与持久化集成耦合在一起,无法测试核心功能,也无法做到技术/框架无关。
在我看来,为了将领域对象与持久层分离,没有必要复制这些对象。这样做会增加代码冗余,而使用这些对象作为DTO是完全可行的。如果有必要,您总是可以使用单独的类,但我不会把这视为铁则,这会浪费时间,而时间是宝贵的。
在DDD社区中发现的一些内容
Chris Richardson发布的帖子 * 如果你想将JPA排除在领域模型之外,则使用XML而不是注释(我从来没有喜欢过ORM注释,因为它混淆了关注点)
个人而言,我很喜欢使用注释,XML对我来说总是容易出错,字段名称的微小更改就需要手动更改XML。如果您想重构域中的单个类,则可能需要更改多个文件,而不能自动处理。 但是最近,我一直在重新考虑这一点,因为我希望能够在项目中使用多个持久选项。我不想让任何与持久性相关的东西进入我的域,因此XML是一个选项。 尽管如此,有时候会遇到没有直接映射的情况,或者仍然想要使用注释,因为它们非常容易更改,并且可以直接看到代码。 我最近做的事情是将我的业务域类创建为抽象类,并使用另一个扩展它以进行持久化。类似于这样:
public abstract class Persona {
private Set<State>states;
public boolean inState(State state){
return states.contains(state);
}
}
@Entity
public class PersonaSql extends Persona {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String statesDefinition;
@PrePersist
void prePersist(){
this.statesDefinition = mapStatesSetToString();
}
@PostPersist
void postPersists(){
this.states = mapStatesStringToSet();
}
}