[Architecture Design] DDD经验分享 (上)
前言
身为一个开发人员,应该会有听过「软件开发流程」、「领域驱动开发」等等,这些开发技术名词。但是...开发人员心底话,包含我自己都觉得:数据文件都写的跟天书一样,模模糊糊的、项目压力下赶工都来不及了,谁有空搞这些的东西。
今天要来扭转这种印象,让开发人员搞懂「软件开发流程」、「领域驱动开发」这些开发技术。并且以自身的开发经验,说明这些开发技术该在哪用、怎么用。让项目的开发不再是无中生有,而是一个循序渐进的过程慢慢「长」出来的。
*在文章开始之前,一定要先提一个最重要的重点:开发技术没有最好的只有最适合的。硬搬教条式的项目到自己团队中,让成员做的很累,这样一定不会长久。例如用来当作本篇文章议题内容的软件开发流程,也是采纳各家技术数据,最终经过调整、整合之后才得到的成果。依照团队开发习惯,去融会贯通各种开发技术的长处,才是能够走长远的道路。
定义
首先我们先来为今天要讲解的两个开发技术:「软件开发流程」、「领域驱动开发」,做一个简单的说明跟定义。
「软件开发流程」定义「做甚么」
「软件开发流程」是某某大老提出来的(我也不知道是谁...)。将开发一个软件应该完成的工作,切割成为一组有开发优先级的软件开发阶段。而软件开发流程的实做模型有很多种,像是:瀑布式、螺旋式....等等。
一个定义清晰的软件开发流程,就像是一份SOP让开发人员参考。让开发人员在每个软件开发阶段,知道现在该做甚么、下一步该做甚么。聚焦该做的事、不让思考发散。简单的说,软件开发流程定义做甚么。
「领域驱动开发」定义「怎么做」
「领域驱动开发」是Eric Evans提出来的,并且将内容整理成了一本Domain Driven Design。它定义了一套开发用的思考逻辑,用以贯穿整个软件开发流程。
相信开发人员都有用过很多的开发工具,在每个软件开发阶段里分析设计系统。例如:Use Case、类别图、顺序图...。但是说真的,大部分的数据文件,都只有介绍这个阶段该用某某工具、图该怎么画。至于图画完了再来要做甚么,每个阶段产出怎么串起来。都写的有看没有懂...可以说大部分的资料文件,没有一个把软件开发流程工作全部贯穿的思想。在这样的情况下,每个阶段产出就都只是零碎并且不连贯的拼图碎片,实用的价值大大的降低。
「领域驱动开发」就是要解决这件事。它定义了一套开发用的思考逻辑,贯穿每个软件开发阶段。让开发人员在每个软件开发阶段,知道现在该怎么做、接下来怎么做。简单的说,领域驱动开发定义怎么做。
软件开发流程 – 范例
知道了,软件开发流程定义做甚么、领域驱动开发定义怎么做。本篇文章就以一个简化的软件开发流程跟领域驱动开发做为议题内容。说明这些开发技术该如何搭配使用,并且又如何能让开发工作更轻松快速完成。接着就来看看,今天所要说明的,软件开发流程里各个软件开发阶段的定义:
需求分析阶段 (RA) : 做甚么
「需求分析阶段」主要的工作是收集客户的需求并且定义项目的范围。简单的说,就是要先了解整个项目要做甚么。
系统分析阶段 (SA) : 怎么做 - 架构设计
「系统分析阶段」主要的工作是对客户的需求内容,提出解决方案并且分析系统架构。简单的说,就是要先初步的决定怎么做,并且做好整个系统架构的设计。
系统设计时间 (SD) : 怎么做 - 模块设计
系统设计时间」主要的工作是对设计完成的系统架构,做每个功能模块的对象设计。简单的说,就是要开始细部的决定怎么做,将系统架构内的功能模块做分析跟设计。
系统实做阶段 (Implement) : 动手做
「系统实做阶段」主要的工作是将完成的系统架构设计,变成实际执行的程序代码。简单的说,也就是实际动手下去做,把前面几个阶段分析设计出来的架构模块一一的实现。
上列数据是本次议题,用来当作议题内容的简单软件开发流程。这个软件开发流程抽离了项目管理相关的技术细节,只专注在开发人员所应该完成的工作。这样的抽离解说方式,是希望让开发人员更专注在开发相关的知识。当开发人员掌握了每个软件开发阶段该完成的开发工作。回头再学习公司内部使用包含项目管理相关的软件开发流程,才会有事半功倍的效果。
到了这边经过简单的介绍,开发人员应该对于本次议题所使用的软件开发流程,有一定程度的认识。接着后续的章节,就针对这个软件开发流程,做每个软件开发阶段的内容说明。
需求分析阶段 (RA)
「需求分析阶段」主要的工作是收集客户的需求并且定义项目的范围。一般会采Use Cases、Prototype等等工具,来完成需求分析的工作。最终将收集完毕的需求数据,整理成一份「软件需求规格书」。
当然啦...以我碰到的真实状况,一般都是业务去跟客户做需求访谈。也不会管Use Cases、Prototype之类的东西,就是单纯的先把案子签下来。好一点的业务,会整理一份写满功能的列表,烂一点的就是口头说案子拿下来了。后续的工作就全部都给开发人员去收尾,做需求分析的动作。其实不管如何,该做的工作还是要做,只是谁做而已。
针对需求分析阶段,前面有说过会使用Use Cases、Prototype等等工具,来完成需求分析的工作。这些工具很强而有力,可以帮忙捕捉到客户的需求。但是实际使用这些工具,会发现捕捉到的只是客户表面的需求。对于客户真正要解决问题的相关知识,只能透过开发人员的经验去做分析设计的动作。
之前有一本「QBQ!问题背后的问题」很火红,它说明要解决的是问题根源,而不是只处理表面浮现的问题。跟客户做需求访谈也是一样,不是单纯客户要甚么就做甚么。而是要去了解客户专业领域的领域知识,针对要项目的内容做访谈,抽取并且封装领域知识、定义领域名词。用这些领域知识来理解、解决客户的问题。这样才能真正提出客户所需要的解决方案,解决客户要解决的问题。这也就是领域驱动开发所提出来的「领域模型」概念。
需求分析阶段 (RA) – 领域模型
上图是一个门禁系统相关的领域模型。它用很抽象的方式描述了在门禁相关领域,所使用到的领域知识、以及专有的领域名词。我们可以这样去看这张图描述的内容:
- 一个门上面会有安装一部卡片阅读机。
- 一个门可以让好几个使用者通过。
- 一个卡片阅读机可以控制一个门的开关。
- 一部卡片阅读机上面会有很多刷卡纪录。
- 一部卡片阅读机可以让好几张卡片通过。
- 一个刷卡记录会记录一个卡片阅读机、以及一张卡片。
- ......
这个领域模型的建立,是在跟客户做需求访谈的过程中。了解客户专业领域的领域知识后,经过抽取封装领域知识、定义专有的领域名词...等等步骤,最后绘制而成。透过这样抽象的对象模型,将客户专业领域的领域知识,转化成为可讨论、可记录的模型数据。并且这个领域模型不是一个独立的工作项目,领域模型要与Use Cases、Prototype等等数据做整合。必须要可以通过领域模型来完整解释说明,与客户访谈所记录下来Use Cases、Prototype这些数据。例如说,某个Use Case内记录了客户想要「设定使用者,通过哪个门」,那在领域模型上就要可以透过抽象的对象模型,去找到这样的抽象描述:「使用者拥有一张卡,它可以使用这张卡,去使用卡片阅读机把门打开然后通过」。当领域模型可以 通过所有Use Case的检验,也就验证了领域模型的正确性。开发人员就可以安心的将领域模型,带入下一个开发阶段做使用。
待续...
期許自己~
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。