夜雨聆风学习资料网

ARTICLE · 1034677

第10讲:软件系统建模:领域概念模型

第10讲:软件系统建模:领域概念模型
软件系统并不是凭空产生的。一个软件通常是为了解决某个现实领域中的问题而开发的。例如,图书馆管理系统面对的是“图书借阅”领域,网上购物系统面对的是“商品交易”领域,医院信息系统面对的是“患者就诊”领域,学校教务系统面对的是“课程、选课和教学管理”领域。
在开发软件之前,我们首先需要理解这个领域中有哪些重要的概念,以及这些概念之间有什么关系。
例如,在图书馆借阅业务中,我们会遇到:读者、图书、作者、借阅、图书馆,这些词。在网上购物业务中,则可能出现:客户、商品、购物车、订单、支付、物流。这些概念来自软件系统所要解决的问题领域(Problem Domain)。对这些概念及其关系进行抽象和组织,就形成了领域概念模型(Domain Conceptual Model)
简单来说:领域概念模型是对软件系统所处问题领域中的重要概念、概念之间关系以及重要业务属性的抽象描述
它回答的主要问题不是“程序应该怎么实现”,而是:这个领域中有什么重要的东西?这些东西有什么特征?它们之间有什么关系?
例如,对于网上购物系统,可以建立一个非常简单的领域概念模型:
这里的“客户”“订单”“商品”“商品分类”都是领域中的重要概念。
领域概念模型强调的是理解问题领域,而不是直接设计程序。因此,在模型中使用“客户”“订单”“商品”这样的业务概念,比一开始就考虑 CustomerController、OrderService、ProductRepository 更合适。
1. 为什么需要领域概念模型
软件项目中经常出现这样一种情况:开发人员能够编写代码,却没有真正理解业务。
例如,开发一个网上购物系统时,如果开发人员没有弄清楚:什么是订单?什么情况下订单成立?一个订单可以包含哪些商品?商品和订单之间是什么关系?支付发生在什么时候?取消订单意味着什么?即使代码可以运行,也可能无法正确解决实际业务问题。
领域概念模型的作用,就是帮助开发团队在编码之前建立对业务领域的共同理解
它主要具有以下几个作用。
1.1 帮助理解需求
自然语言需求往往比较复杂。通过提取其中的重要概念,可以把散乱的需求信息组织起来。
例如:客户可以购买商品。客户提交订单后,可以选择支付方式完成支付。订单包含多个商品。经过概念分析,可以得到:客户、商品、订单、支付方式等概念,以及它们的关系:客户─── 订单、订单─── 商品、订单─── 支付方式。这样,原本分散在文字中的信息就形成了一个结构化模型。
1.2 建立开发人员和业务人员之间的共同语言
软件开发往往需要业务人员、产品人员、分析人员、设计人员和程序员共同参与。
不同角色使用的语言可能不同。例如:业务人员说“客户下单”;产品人员说“订单提交”;程序员可能想到 createOrder();数据库设计人员可能想到order 表。
领域概念模型可以帮助大家围绕相同的业务概念进行讨论。因此,领域概念模型不仅是一张图,也是团队进行需求沟通的一种共同语言。
1.3 为软件设计提供基础
领域概念模型关注问题领域,但它也可以为后续的面向对象设计提供基础。
例如:领域概念有:Customer、Order、Product、Payment。软件设计时的概念有Customer、Order、Product、PaymentService、Repository、Controller。
需要注意,领域概念模型中的概念并不一定会一一对应到最终代码中的类。它是后续软件设计的重要输入,而不是代码结构本身。
1.4 帮助发现需求中的遗漏和矛盾
建立模型的过程中,经常可以发现需求中的问题。例如,需求说:一个订单可以包含多个商品。进一步询问:商品数量保存在哪里?如果一个订单中购买了 5 本《软件工程》书,这个“5”应该属于订单还是商品?继续分析后,我们可能发现需要引入:OrderItem,形成:Order ◆──── OrderItem ──── Product。此时模型不仅描述了概念,也帮助我们发现了原始需求中没有明确表达的重要信息。注:◆────表示构成关系,────表示关联关系。
2. 领域、概念与概念模型
理解领域概念模型,需要区分三个容易混淆的概念:领域、领域概念和概念模型。
2.1 什么是领域
领域是软件所要解决的问题范围。例如:图书馆管理是一个领域;网上购物也是一个领域;大学课程管理同样是一个领域。
领域并不一定对应某个具体的软件系统,而是软件所处的现实业务范围
2.2 什么是领域概念
领域概念是领域中具有业务意义的重要概念。
例如,在“网上购物”领域中:客户、商品、订单、支付、物流都可能是重要的领域概念。而:按钮、文本框、数据库连接、HTTP请求、JSON对象,虽然可能出现在软件实现中,但通常不是网上购物领域本身的核心业务概念。
这体现了领域概念模型和程序设计模型之间的区别。
2.3 什么是概念模型
我们并不是把领域中的所有东西全部列出来,而是选择与当前问题相关的重要概念,并描述它们的关系。
例如,一个网上购物系统可能形成:
这就是一种概念模型。因此可以把它概括为:领域是我们要研究的范围,领域概念是这个范围中的重要业务概念,领域概念模型则是对这些概念及其关系进行组织后的抽象模型。
3. 如何识别领域概念
建立领域概念模型的第一步,是从需求描述中识别重要的领域概念。
一种常见的方法是名词分析法
例如:图书馆允许读者借阅图书。读者需要使用读者证进行借阅,每次借阅都有借阅日期和应还日期。一本图书可以被不同读者在不同时间借阅。从这段需求中,可以找到:图书馆、读者、图书、读者证、借阅、借阅日期、应还日期。这些都是候选概念。但接下来必须进行筛选。
不能简单地认为:“所有名词都是类。”
例如:借阅日期、应还日期,更可能是某个概念的属性。而:读者、图书、借阅则具有更明确的领域意义。
因此,识别概念通常需要考虑以下问题:
这个概念是否具有业务意义?例如,“订单”显然具有业务意义。
这个概念是否需要保存信息?例如,订单需要保存:订单号、创建时间、状态、金额。
这个概念是否需要参与其他业务关系?例如,订单与客户、订单项、支付等概念存在关系。
这个概念是否需要独立描述?如果一个概念有自己的属性、关系和业务规则,那么通常值得作为独立概念进行建模。
4. 识别领域概念的常用线索
除了寻找名词之外,还可以从需求中的其他语言线索发现概念。
名词、名称短语
名词是最直接的线索:客户、订单、商品、课程、学生、教师、图书、账户等名词。
动作
动词可以帮助我们发现概念之间的关系或业务行为:客户创建订单、学生选择课程、教师教授课程、读者借阅图书。
例如:学生选择课程。可以发现:Student、Course,以及二者之间的关系:Student ─── 选择 ─── Course。如果“选课”还需要记录:选课时间、成绩、状态、那么“选课”本身也可能成为重要概念。
属性描述
需求中对某个对象的描述也可以帮助确认概念。
例如:每个订单都有订单号、创建时间、状态和总金额。这些信息帮助我们确认:Order确实是一个重要领域概念。
业务规则
业务规则尤其重要。例如:一个订单至少包含一个商品。这条规则说明Order 与Product 之间存在重要的结构关系。又如:每个学生最多只能选择一门相同课程。这可能进一步帮助我们确定选课 等概念及其约束。
5. 建立概念之间的关系
识别概念之后,需要进一步分析:这些概念之间有什么联系?常见的关系包括:属于;拥有;包含;使用;创建;管理;参与;依赖
例如:一个客户可以创建多个订单,可以表示:Customer 1 ───── 0..* Order。一个订单包含多个订单项,可以表示:Order 1 ───── 1..* OrderItem。一个订单项对应一个商品,可以表示:OrderItem * ───── 1 Product。通过这些关系,可以逐渐形成领域结构。
需要特别注意的是,关系不是为了“让图看起来完整”而添加的。每一条关系都应该能够从需求或领域知识中找到依据
6. 多重性:描述概念之间的数量约束
领域概念模型不仅需要说明“谁和谁有关系”,还需要说明:一个对象可以和多少个另一个对象发生关系?这就是多重性
例如,Customer 1 ───── 0..* Order,表示:一个客户可以有零个或多个订单,而一个订单对应一个客户。再例如,Teacher 1 ───── 1..* Course,可以表示:一个教师负责一门或多门课程。
常见多重性包括:
1       恰好一个
0..1    零个或一个
0..*    零个或多个
1..*    一个或多个
*       多个
多重性实际上是在模型中表达业务规则。
例如:每个订单必须属于一个客户。可以表达为:Customer 1 ───── 0..* Order。如果需求发生变化一个订单可以由多个客户共同创建,那么关系就需要重新分析
因此,多重性不是图形上的装饰,而是业务约束的一种形式化表达。
7.  将复杂关系建模为概念
在领域建模过程中,一个非常重要的技巧是:如果两个概念之间的关系本身具有重要信息,就可以把这条关系提升为一个独立概念
例如:学生选择课程。最简单的模型是:Student * ───── * Course。但是,如果系统还要求保存:选课时间、成绩、选课状态,那么简单的多对多关系就不能完整表达这些信息。此时可以引入:Enrollment(选课),形成:Student 1 ───── 0..* Enrollment─────>Course。其中:
Enrollment
---------------------
enrollDate 
score
status
类似的情况还有:Customer ─── Address。如果地址需要保存:省、市、区、街道、邮政编码,并且客户可以拥有多个地址,那么Address 可能需要成为独立概念。
再例如:Reader ─── Book。如果借阅关系需要记录:借阅日期、应还日期、归还日期,那么可以建立:Reader ─── BorrowRecord ─── Book。这里的BorrowRecord也是独立概念。
这种建模方法对于实际系统尤其重要。
8. 从领域概念模型到 UML 类图
领域概念模型和 UML 类图之间存在密切联系。领域概念模型关注:问题领域中有什么,以及它们之间有什么关系。UML 类图则可以使用标准化图形进一步表示:类、属性、操作、关联、泛化、聚合、组合、依赖、多重性等。
例如,领域模型可能首先表示:客户───── 订单、订单───── 订单项、订单项───── 商品。进一步可以形成 UML 类图:
因此,在面向对象软件工程中,可以把两者理解为:需求→发现领域概念→建立领域概念模型→使用 UML 表达模型类图)→进一步进行软件设计→实现代码。
不过需要强调:领域概念模型不是软件设计类图的简单同义词
领域概念模型强调“问题是什么”,而详细设计类图还需要考虑“软件应该如何实现”。
例如:Customer、Order、Product属于领域概念。而OrderController、OrderService、OrderRepository、DatabaseConnection 则更多属于软件实现和设计层面的概念。
9. 一个完整案例:网上购物系统
下面通过一个综合案例说明如何建立领域概念模型。
假设有如下需求:客户可以浏览商品并将商品加入购物车。客户可以从购物车中创建订单。一个订单包含多个订单项,每个订单项对应一种商品,并记录购买数量和成交价格。客户提交订单后可以进行支付。订单支付成功后进入待发货状态。
首先寻找候选概念:客户、商品、购物车、订单、订单项、支付。
进一步分析这些概念之间的关系。
客户拥有购物车:Customer 1 ───── 1 Cart。
购物车包含多个购物车项:Cart 1 ───── 0..* CartItem。
购物车项对应商品:CartItem * ───── 1 Product。
客户可以创建订单:Customer 1 ───── 0..* Order。
订单包含订单项:Order 1 ───── 1..* OrderItem。
订单项对应商品:OrderItem * ───── 1 Product。
订单还需要进行支付:Order 1 ───── 0..* Payment。
于是,可以形成一个基本的领域概念模型:
这里需要注意模型并不一定只有一种正确答案。例如,“支付”是否应该作为独立概念,要根据系统需求决定。如果支付需要保存支付时间、金额、支付方式、支付状态等信息,那么建立 Payment 概念就很自然;如果当前模型只关心“订单是否已支付”,也可以暂时将其作为 Order 的一个属性。
这说明:领域模型不是对现实世界的完整复制,而是为了当前软件问题选择适当范围和粒度的抽象
10. 如何判断领域模型的粒度
建立领域概念模型时,一个重要问题是:到底应该建多少个概念?建得太少,模型无法表达重要业务;建得太多,又会使模型复杂难懂。
例如,网上购物系统中:Customer、Order、Product是非常明显的核心概念。
但下面这些概念是否都需要建立,则需要根据建模目的判断:Button、WebPage、Database、HTTPRequest、JSON、Mouse、Screen,这些通常不是当前业务领域的核心概念,而是计算机里的概念。
另一方面,如果系统明确需要管理:Coupon、Shipment、Payment、Refund、Invoice,那么这些概念就可能具有独立的业务意义。
因此,可以遵循一个基本原则:只把对当前问题有重要业务意义、需要被讨论、需要被描述或需要参与业务规则的概念纳入领域模型。
11. 常见错误
11.1 把软件实现概念当成领域概念
例如,开发购物系统时,一开始就建立:Controller、Service、Repository、DAO、Database,这些概念属于软件设计和实现层面,而不是购物业务领域本身。领域模型应该首先关注:Customer、Product、Order、Payment、Shipment1
11.2 把所有名词都作为概念
需求中出现的每个名词都不应该直接成为一个概念。例如:客户的姓名、电话号码和地址。通常可以表示为:
Customer
----------------
name
phone
address
而不是:
Customer ─── Name
Customer ─── Phone
Customer ─── Address
是否独立建模,需要根据业务复杂程度和需求判断。
11.3 忽略关系本身的信息
例如:Student * ───── * Course,如果系统要求记录成绩,那么仅仅建立这条关系是不够的。应该考虑:Student ─── Enrollment ─── Course,并在Enrollment 中保存:score、enrollDate、status。
11.4 没有表达多重性
只画:Customer ───── Order,无法表达一个客户可以拥有多少订单。如果需求中存在明确约束,就应该表示:Customer 1 ───── 0..* Order。
11.5 过早加入实现细节
在领域建模阶段就加入:OrderController、OrderService、OrderRepository、MySQLDatabase,容易使读者混淆“问题领域”和“软件实现”
领域建模应该先回答:系统要解决什么问题?而不是马上回答:代码应该怎么写?
11.6 追求唯一的“标准答案”
领域概念模型具有一定的抽象性。同一需求可能存在多个合理模型。
例如,“支付”既可以作为订单的一个属性,也可以作为独立概念;“地址”既可以作为客户属性,也可以成为独立概念。
判断模型是否合理,关键不是:“是不是和老师画的一模一样?”而是:“模型是否能够准确表达当前需求中的重要概念、关系和业务规则?”
12. 领域概念模型的建立过程
综合前面的内容,可以形成一个比较稳定的建模流程。
在实际工作中,这个过程通常不是一次完成的。
我们可能先得到:Customer、Order、Product,然后发现订单需要记录商品数量,于是增加:OrderItem,再发现订单需要支付,又增加:Payment。因此,领域模型构建通常是一个逐步发现、逐步完善的过程。
13. 领域概念模型与数据库模型的区别
学生还经常把领域概念模型和数据库 ER 模型混淆。二者虽然有联系,但关注点不同。领域概念模型关注:业务领域中有什么概念,以及概念之间有什么关系。数据库模型关注:数据应该如何组织和存储。
例如,领域模型:Customer ───── Order,数据库设计可能进一步变成:
领域模型中的概念不一定直接对应一张数据库表。例如:Order。在程序设计和数据库设计中可能分别采用完全不同的结构。因此,应该避免把:领域概念=数据库表。不能简单地画上等号。
14. 领域概念模型与用例的关系
领域概念模型通常与需求分析阶段的用例(Use Case)密切相关。
例如,用例:“客户提交订单”。在这个用例中可能涉及:Customer、ShoppingCart、Order、OrderItem、Product、Payment。通过分析多个用例,我们可以逐渐发现整个领域中的核心概念。
因此,可以形成:用户需求→用例分析→识别领域概念→建立领域概念模型→完善业务规则。
同时,领域模型也可以帮助我们检查用例描述是否完整。
例如:客户提交订单。进一步问:订单包含什么?谁拥有订单?商品数量在哪里记录?订单什么时候创建?支付在哪里发生?这些问题都会推动领域模型进一步完善。
小 结
领域概念模型是软件工程中连接需求分析与软件设计的重要工具。它的核心目标不是描述程序如何实现,而是帮助开发团队理解:软件要解决的现实问题是什么?这个问题领域中有哪些重要概念?这些概念之间存在什么关系?有哪些重要的业务规则?
建立领域概念模型时,可以遵循:确定领域→ 识别概念 → 区分类与属性 → 分析关系 → 确定多重性 → 发现关系概念 → 检查业务规则 → 调整模型粒度。
学习领域建模时,应特别注意以下几点:
① 领域概念来自问题领域,而不是程序实现;
② 不是需求中的所有名词都应该成为概念;
③ 概念应该具有明确的业务意义;
④ 概念之间的关系同样重要;
⑤ 多重性可以表达重要的业务约束;
⑥ 关系本身如果具有重要信息,可以将其建模为独立概念;
⑦ 领域模型不是数据库表结构;
⑧ 领域模型不是最终的软件设计;
⑨ 同一个需求可能存在多个合理的领域模型;
⑩ 判断模型的关键是它是否能够准确、清晰地表达问题领域。
从软件工程的角度看,领域概念模型实际上完成了一次非常重要的转换:现实世界→问题领域→领域概念→概念模型→软件设计→程序实现。其中最关键的一步,是把现实世界中的复杂问题抽象成我们能够理解、讨论和设计的概念及其关系。这正是软件工程中建模工作的核心价值。
附录:领域概念模型的表达(描述)方式
在表达领域概念模型时,可以使用 UML 类图,也可以使用概念关系图、概念图等其他形式。关键并不在于使用哪一种画图工具,而在于模型是否准确地表达了领域中的重要概念、概念之间的关系以及必要的业务约束。常见的几种表达方式列表如下。

主要表达什么

适合什么时候用

UML 类图

概念、属性、概念之间的关联

最经典的领域模型表达

ER 图

实体、关系、基数

偏数据/信息结构时

领域概念关系图

概念之间的语义关系

只想突出“业务概念”,不想带太多技术细节

领域地图 / Context Map

子域、限界上下文及其关系

DDD、复杂业务领域

C4 Context 图

人、系统、外部系统及边界

想从业务领域进一步过渡到系统架构

ArchiMate 领域/业务层图

业务角色、业务服务、业务对象、能力等

企业架构、业务架构

知识图谱 / 概念图

概念及各种语义关系

概念非常多、关系复杂时

BPMN

业务活动、事件、参与者及流程关系

领域概念需要和业务流程结合时

相关学习资料