📄 一句话概括
观点 6:程序=对象之间互相传递消息来驱动——主程序不再是流水线指挥官,而是消息的发送、排队与派发。
📝 本节和前面几节的关系
第四章的程序是一条河(顺序流下去),本节的程序是一张网——对象各自待命,靠消息串起来。
一、什么叫消息
对象 A 调用对象 B 的方法,就是在【A 给 B 发消息】:消息=方法名+参数。 发消息的人不必知道 B 内部怎么办——B 收到后自己决定怎么处理,处理完可以回消息。 这个视角下,程序不再是【指令的序列】,而是【消息的往来】。
二、消息驱动的程序结构
GUI 程序是典型:操作系统把点击、按键塞进消息队列,窗口对象循环取件、派发给该管的对象。 4.7 的事件驱动与 6.5 的队列在这里合流——事件就是消息,队列就是排队通道。 服务器的请求处理(13 课)、消息中间件,用的都是同一套【进队-取件-处理】的骨架。
三、视角转变的意义
过程式问【下一步执行哪句】,消息驱动问【消息发给谁、由谁处理】——设计时的第一问变了。 设计顺序也随之变了:先定对象与职责,再画消息路径,最后才写方法体——与 7.7 的图纸先行正好衔接。 对象之间只通过消息往来,彼此解耦——这也是大型系统能拆能拼的深层原因。
四、动手 Demo:对象间传递消息
搭一个小消息队列:点击、按键进队,窗口和按钮逐条取件处理。
from collections import deque
class Window:
def receive(self, msg):
return "窗口处理了" + msg
class Button:
def receive(self, msg):
return "按钮处理了" + msg
q = deque()
q.append(("点击", "按钮"))
q.append(("回车", "窗口"))
while q:
msg, who = q.popleft()
print(who, "收到", msg)
实跑输出:
--------------------------------------------------------------------
观点 6——通过在对象间传递消息驱动程序
--------------------------------------------------------------------
过程式程序是一条河(第四章), 消息驱动的程序是一张网:
对象各自待命, 靠互相发消息推进。用消息队列模拟一次派发:
队列取件: 点击位置(120,80) -> 按钮
按钮处理了【点击位置(120,80)】
队列取件: 按下回车键 -> 窗口
窗口处理了【按下回车键】
队列取件: 点击关闭 -> 按钮
按钮处理了【点击关闭】
角色 在消息驱动中的职责 6.5 里的原型
------------------------------------------------------
消息队列 先来先处理, 排队等派发 队列 FIFO
窗口/按钮 收消息、做处理 待命的对象
4.7 的事件驱动 + 6.5 的队列, 在这里合流成了 GUI 程序的心脏。
队列先来先处理(6.5 的 FIFO),窗口按钮各自待命(4.7 的事件源)——合流成 GUI 的心脏。 【⚠️ 2026 现状】消息队列早已走出 GUI:Kafka、RabbitMQ 等中间件让服务器之间也靠传消息协作。
30 秒实验
- 观察一次手机操作(如点开 App),猜猜操作系统发出了哪些消息、派给了谁。
- 把 7.3 的汽车改成消息驱动:司机对象发【启动】消息给引擎对象。
常见误区
- 以为消息是多线程专属概念——对象间的方法调用就是消息,单线程也在传。
- 以为发消息要等对方处理完程序才动——消息排队、异步处理正是解耦的关键。
自测三问(点开对答案)
1. 一条消息由什么构成? —— 方法名+参数——调用对象的方法就是发消息。 2. GUI 程序靠什么机制派发消息? —— 消息队列:进队、取件、派发给该管的对象。 3. 消息驱动与 4.7 事件驱动的关系? —— 近亲——事件就是消息,两者在 GUI 里合流。- ☐ 下一节(7.9 观点7:在面向对象编程中使用继承、封装和多态)
相关笔记
- LX_CH4_47 — 事件驱动:消息驱动的近亲
- LX_CH6_65 — 消息队列的底座:队列
- 💻 计算机是怎样跑起来的 · 索引