编程范式是组织代码的世界观,不是能力高低——同一个需求,面向过程按【步骤】组织,面向对象按【角色】组织;选哪门范式优先,取决于你要维护的东西长多大。
2-1/2-2 按【怎么翻译】给语言分了类,本节换一把刀:按【怎么组织代码】分类。C++ 课第十章 class 正式登场、第十一章 inheritance 全套,就是【面向对象】这一范式的完整实战;本节把它放进【范式】的地图里,你看过的代码就有坐标系了。
一、范式是什么:不是语法,是世界观
同样写【算全班平均分】,有人写一串函数按顺序调用,有人先设计一个【学生】类再让类自己报成绩。两种写法都能跑,差别在于代码以什么为单位组织、随规模增长往哪长。这套【组织方式的基本观念】就叫编程范式(Paradigm)。
要点先立住:一门语言可以支持多种范式——C++ 同时支持面向过程与面向对象,Python 也是。所以范式是【语言的能力集合】与【你的写法选择】的组合,不是给语言贴死标签。
二、面向过程:按步骤组织
核心单位是函数。程序=一份待办清单,从头到尾按步骤执行;要复用就抽成函数,数据与函数是分开的。
# 面向过程:数据是数据,操作是操作
scores = [88, 92, 79, 95]
def average(scores):
return sum(scores) / len(scores)
def top(scores):
return max(scores)
print("平均:", average(scores))
print("最高:", top(scores))
小工具、脚本、一次性数据处理——面向过程直给、快、没有仪式感。C 语言是纯粹的面向过程;你在树莓派课第六章写的 Python 脚本,绝大多数也是这个范式。
三、面向对象:按角色组织
核心单位是对象(class 的实例)。把【数据】和【贴身操作这些数据的函数】打包成一个角色,让角色之间互相协作——程序从【一份清单】变成【一个班子】。
# 面向对象:数据与操作打包进【学生】这个角色
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
class ScoreBook:
def __init__(self):
self.students = []
def add(self, student):
self.students.append(student)
def average(self):
return sum(s.score for s in self.students) / len(self.students)
book = ScoreBook()
book.add(Student("小明", 88))
book.add(Student("小红", 92))
print("平均:", book.average())
适合的场景:规模大、会长期维护、多个人协作的项目——角色边界清晰,改一个类的内部不惊动别的类。三大支柱(封装、继承、多态)在 C++ 课第九~十一章已经完整走过一遍,此处只挂锚:封装=数据藏进对象、继承=角色延申出新角色、多态=同一接口不同实现。
四、同一需求两种范式的分界判据
| 判断 | 倾向 |
|---|---|
| 逻辑是一串固定步骤,跑完就完 | 面向过程 |
| 有【东西】要反复创建、状态要长期保存 | 面向对象 |
| 代码只有几百行、单人维护 | 面向过程 |
| 几万行、多人协作、要长期改 | 面向对象 |
| 回调一堆函数指针就能摆平 | 面向过程 |
| 需要继承体系统一一堆相似的东西 | 面向对象 |
注意最后一行埋的钩子:还有第三种声音【函数式】,它对【状态要长期保存】这个前提本身发起攻击——那是下一节的主角。
五、动手 Demo:同一个班级册,两种范式的手感
上面两段代码可以直接连起来跑。把【添加学生并求平均】各做两遍,体会【数据散装】与【数据进角色】的差异:
def procedural():
scores = [88, 92, 79, 95]
return sum(scores) / len(scores)
def object_way():
class ScoreBook:
def __init__(self, scores):
self.scores = scores
def average(self):
return sum(self.scores) / len(self.scores)
return ScoreBook([88, 92, 79, 95]).average()
assert abs(procedural() - object_way()) < 1e-9
print("两种范式结果一致:", procedural())
看到什么算成功:
两种范式结果一致: 88.5
读结果:assert 保证两种组织方式算出的数一模一样((88+92+79+95)÷4 = 88.5)——范式改变的是代码的组织,不是计算的结果。这道防线在重构时极有用:换范式前后各跑一次,结果不一致就说明改坏了。
六、30 秒实验
打开你 C++ 课的任意一篇笔记(比如 10.1 类),把里面的 class 代码在脑子里【翻译】成面向过程的函数版:成员变量变什么?(散装的结构体或全局数据)成员函数变什么?(第一个参数收对象的函数)。翻译三分钟,你就同时拥有了两种范式的【手感】。
七、常见误区
- 【面向对象比面向过程先进,新项目都该用 OOP】——错。范式是工具不是信仰;脚本和小工具用 OOP 只会多出一堆空壳类。Python 社区自己的格言之一:【flat is better than nested】。
- 【C++ 是面向对象语言,C 是面向过程语言,所以 C++ 写出来自动就是 OOP】——错。语言只是提供范式支持,写不写得出来看人;用 C++ 写出满屏全局变量加散装函数的大有人在。
- 【一个项目只能选一种范式】——错。真实项目是混血:主体 OOP,底层算法函数式,胶水脚本面向过程。
自测三问(点开对答案)
1. **编程范式是什么?一门语言只能属于一种范式吗?** 答:是组织代码的基本观念(按步骤还是按角色等);一门语言可以同时支持多种范式,C++/Python 都是多范式。 2. **面向过程的核心单位与面向对象的核心单位各是什么?** 答:函数/对象(class 的实例);前者数据与操作分离,后者数据与操作打包进角色。 3. **什么信号出现时,值得从面向过程切向面向对象?** 答:出现需要反复创建、状态长期保存、边界清晰的【东西】,且项目规模与协作人数在增长——角色化能隔离变化。- ☐ 下一节(2-4)
相关笔记
- C++ 1.1.3 · C++的特点 —— 【多范式语言】的教科书样本
- 树莓派 6-5 · 函数与模块 —— 面向过程范式的日常手感
- Java 1.1 · Java概述 —— 生下来就面向对象的语言
- ⌨️ 编程原理 · 索引 —— 全课路线图