💻 第七章 成为会使用面向对象编程的程序员吧
📄 一句话概括

观点 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 秒实验

  1. 观察一次手机操作(如点开 App),猜猜操作系统发出了哪些消息、派给了谁。
  2. 把 7.3 的汽车改成消息驱动:司机对象发【启动】消息给引擎对象。

常见误区

  1. 以为消息是多线程专属概念——对象间的方法调用就是消息,单线程也在传。
  2. 以为发消息要等对方处理完程序才动——消息排队、异步处理正是解耦的关键。
自测三问(点开对答案) 1. 一条消息由什么构成? —— 方法名+参数——调用对象的方法就是发消息。 2. GUI 程序靠什么机制派发消息? —— 消息队列:进队、取件、派发给该管的对象。 3. 消息驱动与 4.7 事件驱动的关系? —— 近亲——事件就是消息,两者在 GUI 里合流。

相关笔记