mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-11-19 23:53:48 +08:00
fix img
This commit is contained in:
@@ -428,9 +428,9 @@ function hide_canvas() {
|
||||
<p>对限界上下文的识别很难做到一蹴而就。通过对限界上下文的本质与价值的剖析,我们希望从业务边界、工作边界再到应用边界三个层次递进和演化的方式打磨限界上下文,使得它的边界和粒度更加合理,为整个系统的逻辑架构与物理架构奠定良好的基础。</p>
|
||||
<h4>业务边界的识别</h4>
|
||||
<p><strong>领域场景分析中用例划定的主题边界可以作为识别限界上下文的起点</strong>。很明显,主题边界的粒度要大于聚合,但是否与限界上下文的边界重叠呢?我不能给出确定的答案,但毫无疑问,主题边界对应于限界上下文的“业务边界”。对于 EAS 系统而言,我们通过用例图可以得出如下的业务主题:</p>
|
||||
<p><img src="assets/7bd7e7e0-cf84-11e8-a32a-8d282c39c2f0" alt="enter image description here" /></p>
|
||||
<p><img src="assets/7bd7e7e0-cf84-11e8-a32a-8d282c39c2f0" alt="png" /></p>
|
||||
<p>正如前面识别业务主题的过程,我们通过<strong>语义相关性</strong>和<strong>功能相关性</strong>对用例进行了归类,这种归类就是“高内聚”原则的体现。可以确定,<strong>在相同主题内的用例其相关性要强于不同主题的用例</strong>。要识别限界上下文,除了用例级别的归类之外,我们还需要判断主题之间的相关性。如上图所示,我们获得的主题彼此之间存在非常明显的“亲疏”关系,更为“亲密”的主题会组成一个子领域。即使在同一个子领域中,主题之间的“亲疏”关系也有所不同。例如,在项目进度管理子领域中,“项目”主题与“问题”主题的相关性,无疑要比“项目成员”更为紧密。如果再深入分析“项目成员”主题,虽然它与“项目”主题之间存在一定的依赖关系,但从领域概念上,所谓的“项目成员”其实是用户的一种角色,而“项目组”则可以理解为是一个“组织”层级。如此说来,它更像是“组织”主题中组织与角色抽象的一个具体实现,如下图所示:</p>
|
||||
<p><img src="assets/8be67890-cf84-11e8-a32a-8d282c39c2f0" alt="enter image description here" /></p>
|
||||
<p><img src="assets/8be67890-cf84-11e8-a32a-8d282c39c2f0" alt="png" /></p>
|
||||
<p>显然,“项目”主题与“问题”主题代表了不同的用户目标,但各自的业务边界却是非常紧密的,可以考虑合并为一个限界上下文,至于项目与组织的业务边界就确定无疑需要分开了。这种亲疏关系的判断当然需要深入理解业务,但似乎也可以称之为一种设计感觉。这或许就是 Vernon 提到的所谓“经验”罢了。</p>
|
||||
<p>那么有没有什么设计的原则或者依据呢?就以上述分析项目、问题、项目成员之间的亲疏关系为例,它们就好像居住在不同小区的居民。比如说项目和问题住在同一个小区,他们是邻居关系;项目成员住在另一个临近的小区,仍然是邻居,但相隔的距离更远。倘若临近小区的居民和这个小区居民之间又存在亲属关系,意义又有所不同。当一个小区的权益受到侵害时,同一个小区居民的利害关系是休戚与共的。当一个家族的权益受到侵害时,同为亲属的居民的利害关系又绑在一起了。所以,关系的“亲密”程度会因为你观察角度的不同而发生变化,关键在于你选择什么样的判断标准。</p>
|
||||
<p>那么,为何要将“问题”归入“项目”上下文,而不是选择“项目成员”?除了因为项目成员与组织之间存在粘性之外,在概念上,“问题”其实属于“项目”的子概念,在层次上处于“劣势”地位。借用 Kent Beck 在设计上提出的<strong>单一抽象层次原则</strong>,项目与问题其实并没有处在同一个抽象层次。再以“招聘”主题和“储备人才”主题为例,你会发现二者就没有非常明显的“上下级”关系。它们之间的关系或许是比较紧密的,但彼此之间是平等的层次。</p>
|
||||
@@ -464,7 +464,7 @@ function hide_canvas() {
|
||||
<p>针对报表上下文留下来的遗留问题,我们与客户进行了需求上的确认,明确了集团决策层的需求,就是希望系统提供的统计报表能够准确及时地展现历史和当前的人才供需情况。显然,统计报表功能直接影响了系统的业务愿景,是系统的核心功能之一。我们需要花费更多精力来明确设计方案。通观报表上下文提供的用例行为,除了与职能部门管理工作有关的统计日报、周报和月报外,报表的统计结果实际上为集团领导进行决策提供了数据层面的辅助支持。要提供准确的数据统计,就需要对市场需求、客户需求、项目、员工、储备人才、招聘活动等数据做整体分析,这需要整个系统核心限界上下文的数据支持。倘若 EAS 的每个限界上下文并未采用微服务这种零共享架构,则整个系统的数据就可以存储在一个数据库中,无需进行数据的采集和同步,就可以在技术上支持统计分析。另一种选择就是引入数据仓库技术,无论我们选择何种架构模式,都可以采用诸如 ETL 形式完成对各个生产数据库以及日志文件的采集,由统一的数据仓库为统计分析提供数据支持。</p>
|
||||
<p>虽然在分析工作边界时,我们认为报表上下文与其他限界上下文存在强依赖关系,无法支持并行开发,因而考虑将该上下文的功能按照业务相关性分配到其他限界上下文中。如今通过技术分析,虽然这种依赖性仍然存在,但该上下文包含的用例更多地体现了“决策分析”的特定领域。最终,我们还是决定保留该限界上下文,并更名为决策分析上下文。</p>
|
||||
<p>在 EAS 系统中,我们从技术层面再一次讨论了员工上下文和储备人才上下文的边界。从业务相关性的角度看,员工属于员工管理的领域范畴,而储备人才并非正式员工,是招聘的目标。但是,从领域建模的角度讲,员工与储备人才的模型实在是太相似了,如下图所示:</p>
|
||||
<p><img src="assets/c31e84b0-cf84-11e8-a32a-8d282c39c2f0" alt="enter image description here" /></p>
|
||||
<p><img src="assets/c31e84b0-cf84-11e8-a32a-8d282c39c2f0" alt="png" /></p>
|
||||
<p>两个模型除了聚合根的名字不同之外,几乎是一致的。我们是否要对二者进行抽象呢?如下图所示:</p>
|
||||
<p><img src="assets/d0b844d0-cf84-11e8-a32a-8d282c39c2f0" alt="img" /></p>
|
||||
<p>从面向对象的角度看,这种抽象是合理的,也能在一定程度上避免代码的重复开发。然而,这样的设计决定了我们不能将员工和储备人才放在两个不同的限界上下文中,否则就会导致二者的强耦合。若是放在同一个限界上下文,又违背了业务相关性。从技术实现的角度讲,我们必须要考虑员工和储备人才各自的持久化。即使它们在模型上保持了极大的相似度,但是除了一种场景即“从储备人才转为正式员工”用例需要将二者结合起来,其余场景二者都是完全隔离的。即使是这样的业务场景,一旦储备人才转为了正式员工,二者就不存在任何关系了。显然,它们模型相似但在业务上却是<strong>独立进化</strong>的,数据持久化的实现也必须是完全隔离的。因此,我们仍然保留了这两个独立的限界上下文。</p>
|
||||
|
||||
Reference in New Issue
Block a user