JBa*_*ter 6 java domain-driven-design hibernate jpa clean-architecture
您如何看待将持久性模型和领域模型分开?我读到,您不必将持久性问题与业务问题混合在一起(DDD、清洁架构、MartinFowler、Eric Evans 等等)。即便如此,我仍然在所有项目中看到领域模型直接用 ORM 注释进行注释,与持久化机制耦合的领域模型达到了贫血模型并违反了其他原则。
//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class TrainingCycle {
@Id
private Long id;
private String name;
@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
//PersistenceJPA entity
@Entity
@Table(name="training_cycle")
class Discipline {
@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
Run Code Online (Sandbox Code Playgroud)
因此,如果你想遵循干净的原则,你需要拆分域和持久性模型(如下所示)以获得具有业务行为的域模型(这可以避免贫血模型并遵循SRP),因此你需要将域模型映射到当您想要与数据存储区交互时,持久化模型(使用诸如mapToEntity(DomainModel DM)和mapToDomain(PersistenceModel PM)之类的典型方法,可能在映射器/转换器中,也可能在存储库类中),反之亦然,当您想从数据库检索数据时。
class Discipline {
private DisciplineId disciplineId;
private String name;
public Discipline(DisciplineId disciplineId, String name) {
this.disciplineId = disciplineId;
this.name = name
}
}
public class TrainingCycle{
private TrainingCycleId trainingCycleId;
private String name;
private DisciplineId disciplineId;
public TrainingCycle(TrainingCyleId trainingCycleId, String name, DisciplineId disciplineId) {
this.trainingCycleId = trainingCycleId;
this.name = name;
assignDiscipline(disciplineId);
}
public void assignDiscipline(DisciplineId aDisicplineId) {
if(aDisicplineId == null) {
throw new IllegalArgumenException("Discipline cannot be null")
}
this.disciplineId = aDisicplineId;
}
}
@Entity
@Table(name="training_cycle")
class TrainingCycleJpa {
@Id
private Long id;
private String name;
@Column(name="discipline_id")
@JoinColumn(name="discipline_id")
private Long disciplineId; //Referencing by Id because Discipline is another Aggregate ROOT
//EmptyConstructor, getters and setters avoided
}
@Entity
@Table(name="training_cycle")
class DisciplineJpa {
@Id
private Long disciplineId;
private String name;
//EmptyConstructor, getters and setters avoided
}
class TrainingCyleJpaRepository implements TrainigCycleRepository {
public void create(TrainingCycle trainingCycle) {
entityManager.persist(this.mapToEntity(trainingCycle)
}
public TrainingCycle create(TrainingCycleId trainingCycleId) {
return this.mapToDomain(entityManager.find(TrainingCycleId));
}
}
Run Code Online (Sandbox Code Playgroud)
所以讨论/问题是从领域模型中拆分还是不拆分持久性模型?什么时候分裂,什么时候不分裂?在大多数项目中,更不用说在我见过的所有项目中,我看到他们在域模型中结合了持久性模型的注释,而“专家总是在兜售”数据存储是一个细节。
多谢。
是的,这些注释是细节,应该远离干净架构的实体。
不要对干净架构中的名称实体和@Entity持久性框架中的注释感到困惑。它们是不同的东西。
鲍勃叔叔有一段关于干净建筑的视频,最后他说得非常清楚,因为他说:
这些实体不是数据库表的实例。它们通常是由许多数据库表构成的。
在另一个视频中,他讨论了依赖注入和这些框架使用的注释。好吧,依赖注入与您要求的持久性无关,但是这个视频清楚地表明了 Uncle Bob 对用例或干净架构的实体层中的框架注释的看法。
在这段视频中,他非常清楚地表明实体不应该具有持久性细节。是hibernate还是JPA都没关系。
| 归档时间: |
|
| 查看次数: |
1408 次 |
| 最近记录: |