我一直在阅读有关域驱动设计以及如何使用代码优先方法生成数据库的方法.根据我的阅读和研究,围绕这个主题有两种观点:
有1个类同时用作域模型和持久性模型
有2个不同的类,一个实现域逻辑,一个用于代码优先方法
现在我知道意见1)据说简化了在域和持久性模型之间没有太多差异的小解决方案,但我认为它打破了单一责任原则,并且当ORM的约定干扰DDD时引入了许多问题.
令我感到意外的是,有很多关于如何实现意见的代码示例1).但是还没有找到一个如何实现意见的例子2)以及如何映射这两个对象.(可能有这样的例子,但我找不到C#)
所以我试着自己实现一个例子,但我不确定这是不是一个很好的方法.
假设我有一个票务系统,票证有到期日.我的域名模型如下所示:
/// <summary>
/// Domain Model
/// </summary>
public class TicketEntity
{
public int Id { get; private set; }
public decimal Cost { get; private set; }
public DateTime ExpiryDate { get; private set; }
public TicketEntity(int id, decimal cost, DateTime expiryDate)
{
this.Id = id;
this.Cost = cost;
this.ExpiryDate = expiryDate;
}
public bool IsTicketExpired()
{
if (DateTime.Now > this.ExpiryDate)
{
return true;
}
else
{
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用Entity …
我正在编写一个希望遵循 DDD 模式的应用程序,一个典型的实体类如下所示:
@Entity
@Table(name = "mydomain_persons")
class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column(name="fullname")
private String fullName;
@OneToMany(cascade=ALL, mappedBy="item")
private Set<Item> items;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,由于 JPA/Hibernate 严重依赖于实体类的注释,我的域实体类现在被持久性感知注释所污染。这违反了 DDD 原则,也违反了层的分离。它还给我带来了与 ORM 无关的属性的问题,例如事件。如果我使用@Transient,它不会初始化事件列表,我必须手动执行此操作,否则会出现奇怪的错误。
我喜欢域实体是 POJO(或 POKO,因为我使用 Kotlin),所以我不想在实体类上有这样的注释。但是,我绝对不希望使用 XML 配置,这很可怕,这也是 Spring 开发人员首先转向注释的原因。
我有哪些可用的选项?我应该定义一个包含此类注释的 DTO 类和一个将每个 DTO 转换为相应域实体的 Mapper 类吗?这是一个好习惯吗?
编辑:我知道在 C# 中,实体框架允许使用配置类在实体类之外创建映射类,这是比 XML 地狱更好的替代方法。我不确定这种技术是否在 JVM 世界中可用,有人知道下面的代码是否可以用 Spring 完成吗?
public class PersonDbContext: DbContext
{
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Write Fluent API configurations …Run Code Online (Sandbox Code Playgroud)