知识卡片
领域模型决定功能扩展性:人事管理系统案例
内容
定义系统的功能相当于”拍照片”,而领域建模相当于”做透视”:功能需求记录的是系统外在、用户可感知的”应该列表”,是易变的(尤其商业环境急剧变化时);领域模型揭示并模拟问题领域的内在结构,是对问题领域的一层抽象,良好的领域模型不仅支持现有功能,还在一定程度上支持未来可能出现的新需求——这正是可扩展性(在保持现有功能的基础上、扩展实现其他相关功能特性的容易程度)的来源。书中用一个人事管理系统案例具体演示这条原理:最初版本的架构师只根据”统计公司雇员”这类需求设计领域模型(没有考虑可扩展性),公司和雇员是简单的一对多关系。随着时间推移,公司出现职位升迁、员工离职、离职员工又被”挖”回来等真实业务变化,HR经理希望查看员工履历纵览,系统却只能显示某员工的最新职位——由于领域模型的限制,仅扩充应用层根本无法支持”查看员工履历”这个功能,因为领域层压根没有提供、也没有能力提供这样的服务。领域模型必须被重新设计:公司和雇员从一对多关系变成多对多关系,职位、所在部门、薪水这些原本挂在”雇员类”上的属性,被移到了新引入的”雇佣类”(用UML关联类描述雇佣关系)上——这个决策的依据是面向对象分析:姓名、性别很少改变(只需记录最新值),因此仍是雇员的稳定属性;职位、部门、薪水会随职业生涯不断变化,本质上描述的是”雇佣关系”而非”雇员个体”,所以应该挂在雇佣类上,雇佣类还要额外承担记载雇佣时间段的职责。这次改造不仅具体实现要增强、数据库要改变,连子系统接口都随之改变,影响波及了其他子系统——这个案例说明:变化无处不在,但并非无常,问题领域层的核心对象往往相对稳定(如航空订票系统里”航班”“乘客”“优惠策略”这些领域概念从命令行系统到分布式系统几乎从未变过),领域模型决定了软件系统功能可能的范围,模型设计不合理,任何需求变更或新功能增加都可能引起一连串问题。
结构图:
flowchart LR
subgraph 最初模型["最初领域模型(未考虑可扩展性)"]
A1["公司"] -->|"一对多"| B1["雇员\n(含姓名/性别/职位/部门/薪水)"]
end
subgraph 升级后模型["升级后领域模型"]
A2["公司"] -->|"多对多"| B2["雇员\n(仅含姓名/性别/地址)"]
A2 --- C2["雇佣类(关联类)\n职位/部门/薪水/雇佣时间段"]
B2 --- C2
end
最初模型 -->|"新需求:查看员工履历纵览\n触发领域模型重新设计"| 升级后模型