正文
前言
哈喽,老张是周四放松又开始了,这些天的工作真的是繁重,三个项目同时启动,没办法,只能在深夜写文章了,现在时间的周四凌晨,白天上班已经没有时间开始写文章了,希望看到文章的小伙伴,能给个辛苦赞👍哈哈,当然看心情很随意。废话不多说,话说上次咱们对DDD简单说明了下存在的意义,还有就是基于教学上下文的第一次定义,今天咱们就继续说说DDD领域驱动设计中的聚合相关知识,聚合这一块比较多,我暂时决定用两到三篇文章来说说,今天就主要说一下“实体和值对象”的相关概念,其实之前我在定计划的时候,感觉这一块应该很好说,但是晚上吃完饭搜索资料的时候,发现真的好多人对实体理解的还好,但是对值对象真是各种不理解,甚至嗤之以鼻,这一点我感觉是不好的,希望我的读者不要只会说这个不好,那个不对,而是想,这个东西既然产生了,并且一直被大家说着,也有在使用的,肯定有存在的意义,举个栗子,可能今天大家看完对值对象还是蒙胧胧,多想想,多跟着DDD的思想走,也许就好多了,思想真的很难改变,不过只要努力了就是成功了。
好!咱们还是开篇一个小问题,给大家正好一个思考的时间:
咱们从壹大学的后台系统中,每个学生都有自己的家庭住址,肯定会有这样或那样的原因,会变化,那我们是如何设计 Student模型 和 Address 模型的呢,这里只是说代码实现上,数据库其实是对应的。
1、在Students实体中,添加家庭地址属性:省、市、县、街道;
2、新建家庭地址Address实体,在Student中引入地址外键;
3、新建 Students 、Address、StuAdd三个表,在Students中引入List<Address>,一对多;
这个就是我们平时的思路,无论是第一种的一对一(一个学生一个家庭地址),还是第三种的一对多(一个学生多个家庭地址),如果你对这个思路很熟悉,那就需要好好看看今天的文章了,因为上边的这种还是面向数据库数据开发的,希望下边的说明,能让你对DDD的思想有一定的体验。
零、今天要实现蓝色的部分

一、实体 —— 唯一标识
实体对应的英语单词为Entity。提到实体,你可能立马就想到了代码中定义的实体类。在使用一些ORM框架时,比如Entity Framework,实体作为直接反映数据库表结构的对象,就更尤为重要。特别是当我们使用EF Code First时,我们首先要做的就是实体类的设计。在DDD中,实体作为领域建模的工具之一,也是十分重要的概念。
但DDD中的实体和我们以往开发中定义的实体是同一个概念吗?
不完全是。在以往未实施DDD的项目中,我们习惯于将关注点放在数据上,而非领域上。这也就说明了为什么我们在软件开发过程中会首先做数据库的设计,进而根据数据库表结构设计相应的实体对象,这样的实体对象是数据模型转换的结果。
在DDD中,实体作为一个领域概念,在设计实体时,我们将从领域出发。
1、DDD中的实体是什么
许多对象不是由它们的属性来定义,而是通过一系列的连续性(continuity)和标识(identity)来从根本上定义的。只要一个对象在生命周期中能够保持连续性,并且独立于它的属性(即使这些属性对系统用户非常重要),那它就是一个实体。对于实体Entity,实体核心是用唯一的标识符来定义,而不是通过属性来定义。即即使属性完全相同也可能是两个不同的对象。同时实体本身有状态的,实体又演进的生命周期,实体本身会体现出相关的业务行为,业务行为会实体属性或状态造成影响和改变。
如果从值对象本身无状态,不可变,并且不分配具体的标识层面来看。那么值对象可以仅仅理解为实际的Entity对象的一个属性结合而已。该值对象附属在一个实际的实体对象上面。值对象本身不存在一个独立的生命周期,也一般不会产生独立的行为。
2、为什么要使用实体
1、有唯一的标识,不受状态属性的影响。2、可变性特征,状态信息一直可以变化。
二、定义一个实体
public class Student { protected Student() { } public Student(Guid id, string name, string email, DateTime birthDate) { Id = id; Name = name; Email = email; BirthDate = birthDate; } public Guid Id { get; private set; }//模型的唯一标识 public string Name { get; private set; } public string Email { get; private set; } public string Phone { get; private set; } public DateTime BirthDate { get; private set; } }

