📄 一句话概括
设计的手感就是把类当人看、把方法当职责分——实测 4 个类分 10 件事,最忙 4 件、最闲 2 件、极差 2 件;说不清【这事该谁管】就是没分好。
📝 本节和前面几节的关系
10.3~10.6 讲的是三个可以量的目标,这一节讲把它们串起来的那点【感觉】。
一、拟人化:把类当同事
问一句:这件事该谁管? 答得出来,说明职责清楚。 答不出来的时候,通常是三个症状:两个人都想管(重复)、没人想管(漏了)、一个人管所有(上帝类)。 所以拟人化不是文学修辞,是一个检查手段。
二、实测:谁忙谁闲
4 个类分 10 件事:Loan 4 件(忙)、Reader 2 件、Fine 2 件、Book 2 件。
极差 2 件,分配还算匀;极差到 6 以上就该重分了。
注意【忙】不一定是错:Loan 是核心业务对象,多领几件正常——关键是它们属于同一个职责。
三、职责分配的两个判据
内聚:分给同一个类的几件事,是不是围着同一份数据转? 耦合:分完之后,类之间要打多少交道?交道越多越难改。 好分配的样子:每个类都拿自己那份数据、做自己那件事,少问别人。
四、别把拟人化做过头
对象没有主观能动性:它不会【觉得应该这么做】,它只是按写好的规则反应。 所以别说【让对象自己决定】——决定是设计时人做的,运行时它只是执行。 拟人化是设计时的语言,不是运行时的机制,这条界线要清楚。
五、动手 Demo:面向对象设计的【感觉】是拟人化和职责分配
把职责表当成人手分工表,数每个人领几件事。 看最忙与最闲差多少。
duty = {"Reader": ["借书", "还书"],
"Loan": ["登记", "算逾期", "算罚款", "销账"],
"Fine": ["计算", "收款"],
"Book": ["出借", "归还"]}
counts = [len(v) for v in duty.values()]
print(len(duty), sum(counts), max(counts), min(counts), max(counts) - min(counts))
# 4 10 4 2 2
实跑输出:
--------------------------------------------------------------------
面向对象设计的【感觉】是拟人化和职责分配
--------------------------------------------------------------------
把类当人看,**看谁忙死、谁闲着**。实测一张职责与消息数表:
类(当人看) 负责几件事 忙不忙
---------------------------------------
Reader 2 正常
Loan 4 忙
Fine 2 正常
Book 2 正常
类 4 个
职责总数 10 件
最忙的 Loan(4 件)
最闲的 Reader(2 件)
极差 2 件
**极差 2 件**,说明分配得还算匀;**极差到 6 以上就该重分了。**
**拟人化的好处是能立刻说出【这事儿该谁管】**——说不出来,就是职责没分好。
**注意别过头**:对象没有主观能动性,**它只是按规则反应。**
实测:4 个类分 10 件事,最忙 Loan 4 件、最闲 2 件、极差 2 件。 极差 6 以上就该重分;但【忙】本身不是错,关键是那几件事属于同一职责。 拟人化是设计时的检查手段,不是运行时的机制。
30 秒实验
- 把你的类列成一张分工表,数每个人领几件事。
- 挑一件【说不清该谁管】的事,看看是重复、遗漏还是上帝类。
常见误区
- 以为拟人化是文学修辞。它是一个能立刻暴露职责问题的检查手段。
- 以为忙的类一定有问题。核心业务对象多领几件是正常的。
自测三问(点开对答案)
1. 拟人化怎么当检查手段用? —— 问【这件事该谁管】;答不出来通常意味着重复、遗漏或上帝类。 2. 实测分配如何? —— 4 个类分 10 件事,最忙 4 件、最闲 2 件、极差 2 件。 3. 拟人化的界线在哪? —— 它是设计时的语言;运行时对象没有主观能动性,只按规则反应。- ☐ 10.8 进行了职责分配的软件创建的奇妙世界
相关笔记
- 为何化为了通用的归纳整理法 — 职责表的业务来源
- 表示职责分配的时序图和通信图 — 职责怎么画出来
- 进行了职责分配的软件创建的奇妙世界 — 分配之后的收益
- 🧩 面向对象是怎样工作的 · 索引