刚带团队那会儿,我最怕听到一句话:"这个模块,我们先做个面向对象分析。"因为经验告诉我,说完这句话之后,很多人接下来干的事依然是:画页面原型、设计数据库表、然后照着表堆Controller、Service、DAO。真正把面向对象分析(OOA)和面向对象设计(OOD)当成两件不同事情来做,并且做对的人,其实不多。
有一次评审订单模块的设计文档,我看到类图上密密麻麻十几个类,名字分别是OrderController、OrderService、OrderDao、OrderVO、OrderDTO……唯独找不到一个能独立承载业务规则的Order类。这是非常典型的"数据库表驱动的过程式设计",只不过套了一层面向对象的外壳。为了让这类问题少一点,我决定把OOA和OOD的边界、步骤、收益,以及这些年做领域建模的体会,系统地梳理一遍。
这篇文章适合谁?适合那些已经会写面向对象代码,但想搞清楚"类到底怎么设计出来"的初中级开发者;也适合带项目、做技术评审,需要判断"这个分析模型到底好不好"的技术负责人。我不会只给结论,会把每一步背后"为什么这么做"也讲清楚。
1. OOA与OOD的分界线:差一个字母,差一个思考维度
1.1 多数团队的默认状态:分析和设计混着做
先说一个观察。很多项目把"需求评审"当成分析,把"数据库设计"当成设计,然后直接进入编码。这种模式不是不能交付,我见过不少团队靠这套流程也把项目做出来了。但代价是:业务规则散落在各个Service方法里,改动一个业务逻辑要牵连十几个文件,测试难以覆盖,新人接手成本极高。
为什么?因为"业务到底要做什么"和"技术上怎么做"这两件事被揉在一起了。需求变动时,你搞不清楚到底该改业务模型还是改技术实现;技术选型变化时,你又怕牵连业务逻辑。OOA和OOD的核心价值,就是强制把这两个问题分开回答。
1.2 一句话概括两者的差异
OOA回答的是"What":系统要支持的业务流程、业务规则是什么,问题域里有哪些关键概念,概念之间是什么关系。OOD回答的是"How":在给定的技术栈、性能要求、团队结构下,类、接口、模块、数据到底怎么组织。
我用一个生活化的类比。帮朋友安排一次旅行:分析阶段是搞清楚他要去哪里、想玩什么、预算是多少、有没有特别忌口;设计阶段是决定坐高铁还是飞机、住哪家酒店、每天行程怎么排、行李带什么。分析错了,设计得再漂亮,旅行的目的地都是错的。设计错了,目的地再正确,效率、舒适度也会出问题。
两者具体差异见下表:
| 维度 | OOA | OOD |
|---|---|---|
| 关注点 | 问题域、业务概念 | 解决方案域、实现机制 |
| 核心产物 | 问题域模型、分析类图、用例描述 | 设计类图、接口定义、架构分层 |
| 是否依赖技术栈 | 不依赖,换语言换框架不影响 | 依赖,和具体技术选型强相关 |
| 典型提问 | 系统要做什么 | 系统怎么做 |
| 主要变更驱动 | 需求、业务规则调整 | 技术选型、性能、扩展性、成本 |
1.3 分界线画清楚,本身就是工程风险控制手段
这条分界线不是学术洁癖,而是实打实的风险控制。
分析阶段如果就开始争论"这个字段该用varchar还是text""这个列表要不要走缓存",注意力会被实现细节带走,业务规则的完整性很容易漏掉。反过来说,设计阶段如果还停留在业务概念层面,不考虑接口边界、依赖方向、并发访问,写出来的代码就是一盘散沙。把两个阶段的思考维度分开,意味着在正确的阶段只讨论正确的问题,减少无意义的扯皮,也让评审会更有重点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. OOA的完整推进路径:从业务用例走到问题域模型
2.1 第一步,识别对象:从用例文本里捞"名词"
OOA的起点不是数据库,而是用例(Use Case),或者说用户故事/业务场景描述。具体操作很简单:把用例文
