“学习面向对象设计的最佳方式不是死记硬背模式——而是通过扮演角色。”
在本文中,我们将逐步介绍一个逐步介绍CRC卡(类-职责-协作)使用一个现实世界中适合初学者的例子:一个图书馆图书借阅系统无论你是刚开始涉足软件设计,还是正在带领团队工作坊,CRC卡都提供了一种简单、强大且协作性强的方式来建模面向对象系统。
🎯 什么是CRC卡?
CRC卡是一种轻量级的、物理的(或数字的)建模技术,用于面向对象设计。每张卡片代表一个类,并包含三个关键要素:
| 字段 | 描述 |
|---|---|
| 类 | 类的名称(例如图书) |
| 职责 | 该类知道或所做的 |
| 协作者 | 该类需要协作的其他类 |
它们在以下方面尤其有效:头脑风暴, 设计以及验证在开发早期就确定类结构——在编写任何代码之前。
📚 案例研究:图书馆图书借阅系统
让我们设想一个小型公共图书馆,会员可以:
-
按书名搜索书籍
-
借阅可用的书籍(最多有限制)
-
用完后归还书籍
系统必须跟踪:
-
哪些书籍被借出
-
由谁借出
-
何时到期
我们将使用CRC卡片法来逐步发现并优化该系统中的类。
✅ 第一步:找出候选类(头脑风暴名词)
首先阅读场景并提取出名词——这些是潜在的类。
根据描述,我们识别出:
-
图书馆
-
会员(或读者)
-
书籍
-
借阅(或借用)
-
到期日(可能太小)
-
借书证(可能是会员的一部分)
我们进行筛选,只保留最有意义的那些:
✅ 会员, 书籍, 借出
⚠️ 注意:一开始不必担心把所有类都弄对——这就是CRC卡片的魅力所在。你会通过角色扮演发现遗漏的类!
✏️ 第2步:创建初始的CRC卡片
现在,我们分配职责和合作者给每个类。
📘 类:图书
| 职责 | 合作者 |
|---|---|
| 知道它的标题 | — |
| 知道它的作者 | — |
| 知道它的ISBN | — |
| 知道它当前是否可借 | 借出 |
| 被借出 | 借出 |
| 被归还 | 借出 |
💬 图书并不“知道”是谁借了它——它只知道是否有一笔有效的借阅记录。
👤 类:成员
| 职责 | 合作者 |
|---|---|
| 知道姓名 | — |
| 知道会员ID | — |
| 知道当前借出的书籍数量 | 借阅 |
| 借一本书(如果允许) | 书籍,借阅 |
| 归还一本书 | 书籍,借阅 |
| 检查是否达到借阅上限 | 借阅 |
💬 会员自行管理其借阅行为,并通过借阅类检查限额。
📅 类:借阅
| 职责 | 合作者 |
|---|---|
| 记录借了哪本书 | 书籍 |
| 记录是哪位会员借的 | 会员 |
| 记录借出日期 | — |
| 计算到期日期 | — |
| 知道是否逾期 | — |
| 标记为已归还 | 书 |
💬 Loan 类保存了会员与书籍之间的关系,包括时间细节。
🎭 第3步:角色扮演情景——“借一本书”
现在进入有趣的部分:角色扮演将情景当作卡片是真实物品一样来演绎。
📖 情景:柯蒂斯想借《代码整洁之道》,这本书是可借的。
我们一步步来走一遍:
-
会员(柯蒂斯)说:“我想借《代码整洁之道》。”
→ 首先检查:“我已经有少于3本书了吗?”
→ 询问借阅: “我有多少个有效的借阅?” -
借阅回应:“你有一个有效的借阅 → 你可以借书。”
-
会员寻找这本书:“《代码整洁之道》在哪里?”
→ 询问书: “你有空吗?” -
图书 检查: “我有未归还的在借贷款吗?”
→ 询问 贷款: “我有在借的贷款吗?” -
贷款 回复: “没有——你有空!”
-
会员 创建一个新的 贷款 对象:
-
链接到这个 图书 和 会员
-
设置借出日期 = 今天
-
计算到期日期 = 今天 + 14天
-
-
图书 已更新: “现在我有一笔在借贷款 → 我不再有空了。”
✅ 结果:借阅过程感觉自然、分布且逻辑清晰。
🔄 第4步:另一种情景 — “归还图书”
📖 情景:柯蒂斯归还 “代码整洁之道”
-
成员(柯蒂斯)说:“我想归还《代码整洁之道》。”
-
成员找到匹配的借阅(很可能是通过查询借阅这本书和成员信息)。
-
借阅标记自己为已归还.
-
借阅告诉书籍: “你现在又可以借阅了。”
✅ 整洁、清晰且一致——没有类在承担其职责之外的工作。
🔍 第5步:优化并添加缺失的类
角色扮演后,我们注意到一个差距:
❓ 谁通过书名找到这本书?
目前,成员正在询问书直接——但是书不知道如何搜索!
我们需要一个中央协调员.
➕ 新类:图书馆
| 职责 | 合作者 |
|---|---|
| 将新书添加到馆藏中 | 书 |
| 按书名查找书籍 | 书 |
| 注册新成员 | 成员 |
| 处理借书请求 | 成员,书,借阅 |
| 处理还书 | 成员,书,借阅 |
| 了解所有当前借阅 | 借阅 |
💬 图书馆充当中央枢纽——它了解所有书籍、所有成员和所有借阅。
✨ 更新流程:“通过图书馆借书”
-
成员 → 图书馆: “查找书名是‘代码整洁之道’的书。”
-
图书馆 搜索其藏书并返回 书 (或
空如果没有找到)。 -
会员 现在知道这本书存在 → 询问 图书馆: “我可以借这本书吗?”
-
图书馆 检查:
-
这本书可用吗?(通过
Book.isAvailable()) -
该会员是否在借阅限额内?(通过
Loan.countActiveLoans(member))
-
-
如果可以 → 图书馆 创建一个新的 借阅记录 并更新两者 书 和 借阅记录.
-
书变得不可用;借阅跟踪这种关系。
✅ 现在流程就说得通了——这个图书馆负责发现和协调。
🧩 最终CRC卡片总结(适合初学者简化版)
| 类 | 关键职责 | 关键合作者 |
|---|---|---|
| 图书馆 | 管理书籍、成员和借阅;处理借还操作 | 书籍、成员、借阅 |
| 成员 | 了解个人信息;发起借还 | 图书馆、借阅 |
| 书籍 | 存储元数据;跟踪可用性 | 图书馆、借阅 |
| 借阅 | 跟踪借阅历史;计算到期日期;管理归还状态 | 成员、书籍、图书馆 |
✅ 设计原则:每个类都有一个明确的目的,且职责是紧密一致且分布合理.
🌟 为什么CRC卡片如此有效(初学者要点)
| 优势 | 解释 |
|---|---|
| 责任驱动设计 | 迫使你思考:“这个类知道或能做什么?”而不仅仅是存储数据。 |
| 自然发现缺失的类 | 角色扮演揭示了漏洞(比如缺失的图书馆)——无需猜测。 |
| 通过角色扮演获得即时反馈 | 如果流程感觉别扭,你就知道责任分配错了。 |
| 低仪式感且协作性强 | 无需复杂工具——只需索引卡、便利贴或白板。非常适合团队使用。 |
| 连接需求与代码 | 将用户故事转化为真实的类交互。 |
🛠️ 首次CRC会议的快速技巧
-
使用实体卡片(3×5索引卡或便利贴)——更具参与感。
-
每张卡片一个类——保持简单。
-
字迹要大且清晰——其他人应能轻松阅读。
-
大声进行角色扮演——像传递真实物品一样传递卡片。
-
从3–6个核心场景开始(例如:借阅、归还、搜索)。
-
不要追求完美——目标是迭代,而不是最终设计。边做边优化。
-
使用简单且与领域相关的名称——避免使用技术术语。如果团队同意,使用“会员”代替“顾客”。
-
邀请每个人参与——即使非程序员也能帮助发现缺失的责任。
-
之后绘制一个简单的类图——以可视化关系并确认一致性。
-
保持有趣——把它当作游戏。团队参与度越高,结果越好。
🔄 亲自尝试:接下来可以探索的领域
当你掌握了图书系统后,尝试将CRC卡片应用到其他适合初学者的领域:
☕ 咖啡店订单系统
-
类:
顾客,订单,菜单项,咖啡师,收银机 -
场景:下单 → 添加饮品 → 应用折扣 → 支付 → 打印收据
🪙 自动售货机
-
类:
自动售货机,商品,硬币,出货机,找零计算器 -
场景:投入硬币 → 选择商品 → 出货产品 → 返回找零
🎮 知识问答游戏
-
类:
问答,问题,玩家,得分追踪器,游戏会话 -
场景:开始问答 → 回答问题 → 检查正确性 → 显示最终得分
🚗 停车场
-
类:
停车场,汽车,停车位,票据,闸门 -
场景:进入车库 → 停车 → 离开 → 付费 → 取票
这些系统都建立在相同的原则之上:
-
识别名词 → 分配职责 → 角色扮演 → 优化 → 重复。
📌 最后思考:CRC卡片不仅仅是技巧——它们是一种思维方式
CRC卡片真正的力量并不在于卡片本身——而在于它们所激发的对话它们所引发的对话。
当你写下一张卡片并说:“谁负责这个?”或“它需要和谁沟通?”你已经在以面向对象设计者的思维方式进行思考了。
🔥 专业提示:在冲刺规划、技术探索甚至面试中使用CRC卡片,以展示你的设计思维。
它们不仅适用于开发人员——它们适用于任何人参与软件开发的任何人:产品经理、设计师、测试人员和学生。
📎 想了解更多?
👉 下载可打印的CRC卡片模板(PDF或数字版),用于你下一次的工作坊。
👉 尝试一次实时的CRC会议与队友一起进行——分配角色:“你是会员”,“你是书籍”,等等。
👉 分享你的成果——在社交媒体上发布你的卡片,带上#CRC卡片或#面向对象设计之旅标签。
🏁 结论
这个图书馆图书借阅系统是CRC卡片最经典且有效的示例之一——并非因为它复杂,而是因为它简单、易懂且富有洞察力.
只需遵循五个步骤——头脑风暴、卡片创建、角色扮演、优化和迭代——你就可以:
-
自然地发现类
-
清晰地分配职责
-
及早发现设计缺陷
-
团队共建共享心智模型
最重要的是?你不需要是资深开发人员也能做到。
你只需要好奇心、几张卡片,以及愿意尝试的意愿。
✅ 现在轮到你了:拿几张便利贴,选一个简单的系统(比如咖啡馆或自动售货机),尝试使用CRC方法。
📌 记住:好的设计不在于写出完美的代码——而在于提出正确的问题。
而使用CRC卡片,你已经在提出这些问题了。
📌 额外赠送:可打印的CRC卡片模板(文本版)
┌────────────────────┐
│ [类名] │
├────────────────────┤
│ 职责: │
│ - │
│ - │
│ - │
├────────────────────┤
│ 合作者: │
│ - │
│ - │
└────────────────────┘
将此打印在3×5的卡片上,或在Miro、Figma或Google幻灯片等数字工具中使用。
📚 下一步?
想要完整体验一下咖啡馆订单系统使用相同CRC风格的流程吗?
👉 只需说一声——我将一步步发送下一个案例研究,包含卡片、场景和角色扮演!
祝你设计愉快! 🎮🧩💻
- 如何在 Visual Paradigm 中绘制 CRC 卡片: 本逐步指南提供了使用软件专用绘图工具创建 CRC 卡片的说明。
- 理解 Visual Paradigm 中的 CRC 卡片图: 一份概述,解释了这些图表如何用于建模面向对象系统及其交互。
- 如何在 Visual Paradigm 中创建 CRC 卡片图: 一份在社区圈中找到的详细教程,涵盖 CRC 图的创建与自定义。
- Visual Paradigm 中 CRC 图的入门: 一份全面的指南,专注于利用 CRC 图进行面向对象设计和更广泛的系统建模。
- 从类图生成 CRC 卡片: 本次社区讨论探讨了如何利用现有的类图,通过逆向工程自动生成卡片的方法。
- 将 CRC 卡片与类图同步: 一份技术资源,讨论双向建模,以确保卡片与类模型之间的设计一致性。
- CRC 卡片图入门(PDF 指南): 一份可下载的技术资源,解释了 CRC 卡片在系统分析中的核心概念和应用。
- 在 CRC 卡片与类图之间建立链接: 本文强调了在不同建模层级之间保持可追溯性和链接性的技术。
- Visual Paradigm 资源库中的 CRC 卡片模板: 一份资源,包含一个可下载的模板,旨在支持早期阶段的面向对象设计。
- 在不同图表之间移动 CRC 卡片: 一份指南,详细说明了在不同图表之间转移卡片的同时保持数据一致性的方法。













