张逸说

出口成张,逸派胡言

0%

领域驱动战略设计工作坊

在2018年第二届领域驱动设计中国峰会,我作为讲师做了一个领域驱动战略设计工作坊——再现具有实操价值的架构方案。在这个工作坊中,我将敏捷实践中的Inception与领域驱动战略设计结合起来,并引入Event Storming和用例场景分析等方法,带着大家一起糊了墙,玩风暴,算是满意地完成了战略设计的预期目标。在这次工作坊的参与者中,我欣喜地看到了业务同学的加入。这些业务同学敏锐的分析目光与业务感给我们的用例场景分析带来了极好的助力,也为整个工作坊增加了不少亮点。

我把整个工作坊分为了十个步骤,依次为:

  • 确定利益相关人
  • 确定业务期望和愿景
  • 对问题域的共同理解
  • 确定项目的业务范围
  • 确定业务流程
  • 史诗级故事和主故事
  • 运用用例分析场景
  • 通过边界识别限界上下文
  • 上下文映射
  • 领域架构

我选择一些重要步骤对整个工作坊做一个简单的回顾。

对问题域的共同理解

我认为:“对问题域(Problem Domain)的识别其实就是对客户痛点的识别。之所以要开发这个软件,目的就是解决这些痛点,为应对这些问题提供具有业务价值的功能。在识别痛点的过程中,需要始终从业务期望与愿景出发,与不同的利益相关人进行交流,如此才能达成对问题域的共同理解。”在工作坊中,一位业务人员补充了我对问题域定义的不足,她认为问题域不仅是对痛点的识别,还包括系统所要提供的价值

ThoughtWorks的禚娴静则以淘宝和京东的例子提出了她对问题域的看法,她认为,虽然这两家都是电商系统,但二者的核心价值并不相同。淘宝的核心价值是为买家提供物美价廉的商品,京东的核心价值则是提供快速便捷的物流。对于京东而言,物流问题域会作为一个核心领域而存在。

通过分析系统的业务期望和愿景,有团队针对问题域做出了颇具价值的抽象,如下图所示,他们提炼出“需、控、供、决策”这四个核心问题域:

另一个团队则从价值和服务两个维度对整个系统的问题域进行了清晰的划分:

现场探讨了问题域与解决方案域之间的区别,进而也谈到了核心域、子域与限界上下文之间的关系。我的观点可以用这样一幅图来表达:

确定项目的业务范围

之所以要确定项目的业务范围,是为了明确整个系统的边界。明确系统边界是架构设计的重要前提,它一方面可以明确职责划分,了解哪些内容才属于领域驱动设计的范畴;另一方面则可以事先明确当前系统需要与哪些外部系统集成。

我引入了Simon C4模型中的System Context来确定系统的边界:

在这个过程中,我们要将自己设计的系统视为一个黑盒子,假设它已经实现,再来考虑它需要与哪些角色以及外部系统、外部资源进行协作。System Context除了可以帮助我们确定系统的边界之外,还有利于推动我们开展build vs buy的决策。如果是购买第三方软件系统或服务,则该系统或服务就将作为本系统协作的外部系统。

运用用例分析场景

一个主用例可以认为是一个具有业务价值的业务功能。我提出的用例场景分析步骤为:

  • 确定业务流程,通过业务流程识别参与者(Actor);
  • 根据每个参与者识别属于该参与者的用例,遵循一个参与者一张用例图的原则,保证用例图的直观与清晰;
  • 对识别出来的用例根据语义相关性和功能相关性进行分类,确定用例的主题边界,并对每个主题进行命名。

首先,我让学员通过识别系统的参与者驱动用例的识别。一个参与者一个用例图,可以让我们的用例分析既有清晰的分析起点,又能保证用例图的清晰直观:

运用用例进行场景分析时,不必死板地抱着UML的规则行事,但用例图的根本价值仍然值得重视。例如参与者与用例的use关系体现了用例的价值(Why),用例的描述应采用简洁明了的动宾短语,识别用例之间的包含与扩展关系等。在工作坊演练过程中,我让学员使用不同颜色的即时贴来表达用例,例如黄色代表Actor,蓝色代表主用例,绿色代表扩展或包含用例。这样就有助于整个团队在进行场景分析时的沟通与协作,俗称“糊墙”:

当然,你也可以放在桌面上进行:

一旦准确地识别出用例,再根据语义相关性和功能相关性对这些用例进行分组,最后,确定主题边界(Subject Boundary)就变得相对容易了。以下是其中四个团队分别给出的主题边界分组:

这些识别出来的主题边界其实就是限界上下文的候选了。可以看到,不同团队因为需求理解的不同,识别出来的主题边界确实存在差别,但这个差别是非常细微的,基本能就限界上下文的边界达成一致。这些识别出来的用例同时也将作为统一语言的一部分,在后续的领域建模和战术设计中提供非常有价值的指导。

领域架构

在架构层面,我引入了RUP的4+1视图,这样可以使得领域驱动战略设计的成果显得更加系统化,能够为业务人员、开发人员、运维人员提供不同视角的架构指导。例如获得的逻辑视图可以非常清晰地表达系统层面与限界上下文层面各自的逻辑组成:

进程视图则使用时序图针对那些需要异步处理或分布式通信的用例进行了清晰刻画:

至于开发视图则为后续的领域驱动战术设计提供了重要的指导,明确了每个模块(包)的职责以及它们在逻辑架构中所处的位置:

针对这样的战略设计工作坊,我们既要有高屋建瓴的系统理论,又需要让这些理论和方法能够落地,成为具有实操价值的一种工作坊形式。我充分借鉴了事件风暴这种新方法,却又未完全抛弃UML这种老方法,采用各取所长的手段将二者结合起来,形成一种行之有效的设计手法,有助于大家清晰地认识问题域,并通过场景分析寻找解决方案域中最重要的限界上下文。这一方法同样可以帮助我们进行微服务设计,毕竟,从某种角度讲,一个限界上下文就可以等于是一个微服务。

特别强调的是,在整个工作坊设计过程中,我们需要抛开技术因素对我们的干扰,只能由业务来驱动我们的设计。这就需要团队充分地与领域专家或需求分析人员进行沟通和交流。只有在最后确定限界上下文的粒度与边界,以及探讨限界上下文之间的协作时,我们才能揭开技术的面纱,从技术复杂度的角度去进一步地分析,直到得到就目前而言恰如其分的领域架构。

说明:工作坊用到的系统需求文档以及工作坊讲义可以通过关注我的微信公众号。发送“工作坊”消息可获得工作坊讲义,发送“需求”可获得工作坊用到的系统需求文档。