【Day 06】领域驱动设计的战略设计(Strategic Design)

前言

我们常会使用业务性质来界定领域范围(Bounded Context),例如,采购、销售、库存、运输、会计...等,一般而言,这并没有问题,但是,回到中台架构的理念,我们希望透过共享架构的建立,达到复用(Reuse)的能力,因此,以业务性质界定领域范围後,应该进一步进行水平整合,将共有的功能独立出来,才能建构共享、复用的平台。

子领域的切割

企业资源有限,开发团队可能无法在短时间内满足所有业务需求,因此,必须把领域范围区分为核心域(Core domain)、支撑域(Supporting domain)及通用域(Generic domain),然後把焦点集中在核心域,创造竞争优势,支撑域可以外购或外包,配合公司业务的快速发展,例如,餐饮业可以把外送业务直接委托FoodPanda、Uber...等外送平台,至於通用域就必须慎重考虑,例如,权限控管机制关系到单一登入(Single Sign-On, SSO)的重大决策,又客户管理领域牵涉到各部门,如何方便共享并兼顾隐私权的维护,不管是外购或自建,都必须考虑到战略资讯系统的长远规划。以产物保险系统为例,可以作以下的切割:
https://ithelp.ithome.com.tw/upload/images/20210925/20001976MnnVrtq23z.png
图一. 产物保险系统子领域的切割

外部系统的界定

DDD 使用 Context Map 界定与外部系统的关联,DDD发明人Eric Evans将关联按控制(Control)与通讯(Communication)的依存度分为九种,如下图:
https://ithelp.ithome.com.tw/upload/images/20210925/20001976CjwDZUB3Xh.png
图二. 系统关联的类型,图片来源:Domain-Driven Design: Strategic Patterns

九种关联模式说明如下:

  1. 单一领域范围(Bounded Context):两个系统同在一个领域范围,密不可分。
  2. 共享核心(Shared Kernel):两个系统共享一份领域模型,甚至也共享程序码,应该是指函数库(Library)。
  3. 客户与供应商的关系(Customer/Supplier):上下游的关联,上游系统供应资料给下游系统,必须注意承诺与时程(commitment and schedule),例如物联网须定时传输感测资料给资料中心。
  4. 遵奉者(Conformist):上游系统没有强烈动机要提供资料给下游系统,万一上游系统不准时传送资料,下游系统就会很惨,除非它有备案。
  5. 防腐层(Anti-Corruption Layer):下游系统建立一层翻译层(Translation layer),负责上、下游间的资料转换,以避免上游系统的修改。
  6. 开放主机服务(Open Host Service):上游系统定义通讯协定,提供资料交换,例如透过RPC(Remote Procedure Call),外部系统就可以存取主机的各项资源。
  7. 事件出版者(Event Publisher):提供出版/订阅模式,进行资料交换。
  8. 出版语言(Published Language):提供共通的文件格式,例如XML、JSON、Protocol Buffers。
  9. 各行其事(Separate Ways):两个系统无明显关联。

区分这些模式有点政治化,可能因一方比较强势,就会决定使两个系统的关联模式要采用那一种,不管如何,一但决定了,後续架构及设计就需因应发展。

Eric Evans特别提到旧系统的汰换,不要想一步淘汰旧系统,可以利用防腐层模式接通旧系统,再逐步利用新技术,将旧系统的功能一块一块替换掉,这是一个好主意,可以降低风险。

架构分层

为了程序容易扩充与维护,通常我们会对系统架构进行分层,不论是 Client/Server、N-Tier、MVC/MVVM...等,都是将程序的使用者介面(UI)、业务逻辑及资料库存取分离,避免单一档案过大,且混在一起很难修改,DDD也不例外,将架构分为四层,如下图:
https://ithelp.ithome.com.tw/upload/images/20210926/200019764220e6wQyB.png
图三. DDD分层架构,图片来源:Implementing Domain-Driven Design

DDD将中间层分为应用层(Application Layer)及领域层(Domain Layer),领域层包裹领域模型,并将相关业务逻辑涵盖在内,应用层只是薄薄一层,组合相关领域模型,负责安全认证、发送通知、...等事务。另外,DDD强调设计模式(Design Pattern),例如依赖注入(Dependency Injection, DI)可反转图三架构,以宣告式方式产生物件,或是Repository Pattern结合工厂模式(Factory Pattern),可统合一般物件的新增、更新、删除、查询等共通功能,避免每个类别重复撰写类似的程序码。

完整的架构可参考下图:
https://ithelp.ithome.com.tw/upload/images/20210926/20001976czpkOBcIT3.png
图四. 详细的DDD分层架构,图片来源:一文解析DDD中台和微服务设计

结语

由上介绍,战略设计(Strategic Design)相当於架构规划,良好的规划是专案成功的第一步,规划的初衷永远不要忘记:

  1. 聚焦核心域的开发。
  2. 共享与复用。

不要以职场政治为唯一考量。


<<:  AI ninja project [day 26] QLattice -- 基础回归

>>:  Day11 NiFi & NiFi Registry

Day 18 - MSSQL 基本 & 工具介绍

在提到MSSQL前,我们要先有对资料库的一些基本概念。 何谓资料库? 资料库就是储存资料的地方。但比...

Day21 Android - Retrofit(Post)

昨天所说的(Get)主要用於取得api的资料,像是昨天https://jsonplaceholder...

DAY02 - 前端工程师的工作日常

好像很多人对工程师的想像都是埋首写程序, 不用讲话,写程序就好了~ 但其实前端工程师真的不是只有写程...

Day 09:一起了解 Angular 应用程序的启动流程(一)

启动 Angular 开发服务器 我们先打开 VS Code 的终端机面版,输入 npm start...

Swift纯Code之旅 Day25. 「各个TableViewHeader下的Cell显示(2)」

前言 我们已经将第一个Section下的Cell设置完毕了,接下来马上来实作第二个Section的C...