前言
源码地址:
https://github.com/SkylerSkr/Skr3D
领域是DDD的核心要点。在领域层,我们应该处理掉该领域的全部业务。在这里我们只需要操作领域对象。
领域对象如何持久化,领域对象怎么显示到UI层,这些都不是领域层考虑的事情。
我们以电商项目为例,先对电商进行建模。
领域实体:
领域实体就是将领域中遇到的对象进行建模,以实体的方式表达出来。
例如:在电商项目中,主订单下,有多个子订单和收获地址。
public class Order : Entity
{
protected Order()
{
}
public Order(Guid id, string name,Address address, List<OrderItem> orderItem)
{
Id = id;
Name = name;
Address = address;
OrderItem = orderItem;
}
/// <summary>
/// 订单名
/// </summary>
public string Name { get; private set; }
/// <summary>
/// 收获地址
/// </summary>
public Address Address { get; private set; }
/// <summary>
/// 订单详情
/// </summary>
public virtual ICollection<OrderItem> OrderItem { get; private set; }
}
public class OrderItem : Entity
{
/// <summary>
/// 详情名
/// </summary>
public string Name { get; private set; }
public virtual Order Order { get; set; }
}
/// <summary>
/// 地址
/// </summary>
//[Owned]
public class Address : ValueObject<Address>
{
/// <summary>
/// 省份
/// </summary>
public string Province { get; private set; }
/// <summary>
/// 城市
/// </summary>
public string City { get; private set; }
/// <summary>
/// 区县
/// </summary>
public string County { get; private set; }
/// <summary>
/// 街道
/// </summary>
public string Street { get; private set; }
public Address() { }
public Address(string province, string city,
string county, string street)
{
this.Province = province;
this.City = city;
this.County = county;
this.Street = street;
}
}
从这3个实体类中,我们得出以下定义。
聚合根:Order,根实体,在领域中的最小单位,子节点有普通的领域实体和值类型。
普通的领域实体:OrderItem,有独立的标识。
值类型:Address,类似地址这种不需要标识的数据,是一个不可更改的值。比如我在某宝买了东西,地址写了上海,然后去用户模块把自己收获地址改成北京,但是订单的地址应该是根据下单时候填写的才对。
领域对象的CRUD:
我们前面也说了,在领域层里只处理领域内的事情。将领域对象进行建模得到实体,让我们可以用程序操作领域对象。但是我们如何获取领域对象,并将其持久化这都不需要我们关心。我们只需在领域层声明了持久化接口,让基础设施层去实现它。
/// <summary>
/// 定义泛型仓储接口,并继承IDisposable,显式释放资源
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IRepository<TEntity> : IDisposable where TEntity : class
{
/// <summary>
/// 添加
/// </summary>
/// <param name="obj"></param>
void Add(TEntity obj);
/// <summary>
/// 根据id获取对象
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
TEntity GetById(Guid id);
/// <summary>
/// 获取列表
/// </summary>
/// <returns></returns>
IQueryable<TEntity> GetAll();
/// <summary>
/// 根据对象进行更新
/// </summary>
/// <param name="obj"></param>
void Update(TEntity obj);
/// <summary>
/// 根据id删除
/// </summary>
/// <param name="id"></param>
void Remove(Guid id);
/// <summary>
/// 保存
/// </summary>
/// <returns></returns>
int SaveChanges();
}
/// <summary>
/// IOrderRepository接口
/// 注意,这里我们的对象,是领域对象
/// </summary>
public interface IOrderRepository : IRepository<Order>
{
//一些Student独有的接口
Order GetByName(string name);
}
领域对象如何持久化到数据库,这是基础设施层要解决的问题。
我们只需要定义好对领域对象操作的持久化接口即可。
PS:持久化接口操作的是领域对象。
网友评论