美文网首页DDD领域驱动设计
DDD领域驱动设计——领域层

DDD领域驱动设计——领域层

作者: SkylerSkr | 来源:发表于2020-03-21 18:16 被阅读0次

前言

源码地址:
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:持久化接口操作的是领域对象

相关文章

网友评论

    本文标题:DDD领域驱动设计——领域层

    本文链接:https://www.haomeiwen.com/subject/ejduyhtx.html