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
} 
因此,如果你想遵循干净的原则,你需要拆分域和持久性模型(如下所示)以获得具有业务行为的域模型(这可以避免贫血模型并遵循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));
    }
}
所以讨论/问题是从领域模型中拆分还是不拆分持久性模型?什么时候分裂,什么时候不分裂?在大多数项目中,更不用说在我见过的所有项目中,我看到他们在域模型中结合了持久性模型的注释,而“专家总是在兜售”数据存储是一个细节。
多谢。
是的,这些注释是细节,应该远离干净架构的实体。
不要对干净架构中的名称实体和@Entity持久性框架中的注释感到困惑。它们是不同的东西。
鲍勃叔叔有一段关于干净建筑的视频,最后他说得非常清楚,因为他说:
这些实体不是数据库表的实例。它们通常是由许多数据库表构成的。
在另一个视频中,他讨论了依赖注入和这些框架使用的注释。好吧,依赖注入与您要求的持久性无关,但是这个视频清楚地表明了 Uncle Bob 对用例或干净架构的实体层中的框架注释的看法。
在这段视频中,他非常清楚地表明实体不应该具有持久性细节。是hibernate还是JPA都没关系。