《冒号课堂:编程范式与OOP思想》笔记一
首先,要有批判精神和独立思考的能力。
第一课
学会不如会学,会学不如会用,会用不如被用
- 学会:知其所然
- 会学:知所以然
- 会用:人为我用(能将所学灵活运用到实际编程设计中)
- 被用:我为人用(能设计出广为人用的应用程序)
IT行业不同于纯数学,IT最高造诣是活学活用、广为人用。
如果知识是水,我们要挖掘最先涌动的泉眼;如果知识是火,我们要捕捉起初点燃的火花;如果知识是树,其树大根深,不究立固之本则无以知过去;其枝繁叶茂,不握之干则无以知其蓬勃茂盛,不察生长之点无以知未来。
首先,作者的文笔真的好。其次,IT行业大的红利期已经过去了,正逐步进行大浪淘沙。少关注框架,多关注框架背后的思想以及相对底层的知识。
知识之上是思想,思想之上是精神。
原理比单一知识点重要,终身学习、保持好奇比抱残守缺重要。
AJAX:Asynchronous JavaScript And XML(异步的 JavaScript 和 XML)
领域特定语言(Domain Specific Language,DSL)
通用编程语言(General-Purpose Programming Language,GPPL)
- 第一代语言:机器语言
- 第二代语言:汇编语言
- 第三代语言:高级语言
- 第四代语言:面向问题语言(SQL,SPSS)
- 第五代语言:人工智能语言(Prolog,Mercury,OPS5)
面向问题语言:基本属于DSL,只面向某一领域的问题。评判语言优劣,要根据使用语言的主体和面向的对象。第四代和第五代语言与前三代语言的区别在于:重目标轻过程、重描述轻实现。
得形而忘意,无异舍本逐末;得意而忘形,方能游刃有余。
荃者所以在鱼,得鱼而忘荃;蹄者所以在兔,得兔而忘蹄;言者所以在意,得意而忘言。 ——《庄子 · 外物》
一个足够复杂的应用软件开发,为保证快速有效,通常采取的方法是:在宏观管理上选取一些框架以控制整体的结构和流程;在微观实现上利用库和工具包来解决具体的细节问题。框架的意义在于使开发者在特定领域的 整体设计上不必重新发明轮子;库和工具包的意义在于使开发者摆脱底层编码,专注特定问题和业务逻辑。
框架和库的使用,使软件开发变得更加快捷。框架提供了项目的整体设计架构;库透明化底层细节,提供了较高层次的抽象。
库和工具包是为程序员带来自由的,框架是为程序员带来约束的。
学会阅读源码,看懂轮子,修轮子,造轮子。
SSH:Struts、Spring、Hibernate
第二课
命令式编程的世界观是:程序是由若干行动指令组成的有序列表。其方法论是:用变量来储存数据,用语句来执行指令。
过程式编程是在命令式编程的基础上引入了过程、函数。
- 结构化编程:提倡代码具有严谨的逻辑结构。
- 任何程序都可用顺序、选择和循环这三种基本控制结构来表示。
- 满足“单入口、单出口”(SESE)原则。
- 是冯 · 诺伊曼机的基本运行机制。
- 以行动为导向。
- 采用“自顶向下”的设计。
分而治之,解耦合
声明式编程是以目标为驱动的。
声明式编程主要包括函数式编程(FP)和逻辑式编程(LP)。
函数式编程将计算描述为数学函数的求值;而逻辑式编程通过一系列事实和规则来推导或论证结论。
除尾递归外,一般递归比迭代的开销大。
声明式编程的思想类似于抽象。
三种核心编程范式比较:
范式 | 程序 | 输入 | 输出 | 程序设计 | 程序运行 |
---|---|---|---|---|---|
命令式 | 自动机 | 初始状态 | 最终状态 | 设计指令 | 命令执行 |
函数式 | 数学函数 | 自变量 | 因变量 | 设计函数 | 表达式变换 |
逻辑式 | 逻辑证明 | 题设 | 结论 | 设计命题 | 逻辑推理 |
OOP的核心思想可泛化为:以数据为中心组织逻辑,将系统视为相互作用的对象集合,并利用继承与多态来增强可维护性、可扩展性和可重用性。
OOP基础特征:封装性、继承性和多态性。可维护性、可扩展性和可重用性是所有编程范式的目标,不为OOP独有
没有银弹。(No silver bullet)
OOP不可能一统天下,需根据实际应用场景选择或者综合其他编程范式。
如果把整个流程看作一颗倒长的大树,过程式编程自树根向下,逐渐分支,直到每片树叶,类似数学证明中的分析法,即执果索因的逆推法,逐步求精;OOP则从每片树叶开始,逐渐合并,直到树根,类似数学证明中的综合法,即执因索果的正推法,逐步合并。
过程式编程,牵一发而动全身;OOP松耦合,较易维护。
接口粗粒度化:把一些函数包装起来。
相比于重用性,OOP更具易用性:我们重用的是什么?是类吗 ?我觉得是类里面的方法(函数)。也就是说,方法(函数)具有重用性,而OOP提供了类,这比过程式编程更易找到需要的函数,这体现了易用性。
函数是被动的实体,对象是主动的实体。过程式程序的世界是君主制的,主函数是国王,其他函数是臣民。OO程序的世界是民主制的,所有对象都是独立而平等的公民。更进一步,封装使得公民拥有个体身份,继承使得公民拥有家庭身份,多态使得公民拥有社会身份。
那Java是不是就是“君主立宪制”:Java程序必须有一个主类,相当于议会,里面放一些路由之类的控制组件,相当于议会做决策。主类里的main方法相当于国王,负责表面上的各种安排。而其他类就相当于百姓之类,负责具体事务处理。
并发式编程,绝不是简单调用几个API,使用几个关键字这般简单。从宏观的架构设计,到微观的控制流和算法,可能都与串行式编程不同,还要结合运行程序的硬件特点。
并发式编程以进程为导向,以任务为中心,以资源共享与竞争为主线,将系统模块化。
过程式有函数模块,对象式有对象模块,并发式有系统模块。不能独立的看待每个模块,还要考虑到模块之间的相互关联和作用。
并发式与对象式均为传统编程的推广:并发式进程个数为1时即为传统的串行式编程,对象的方法个数为零即为传统的数据类型;均将整个程序系统分解为若干独立的子系统,不同的是一个以任务为单位,一个以对象为单位;子系统之间均能交流合作,不同的是一个以竞争为主题,一个以服务为主题。
合理的并发式设计应该做到:软件易于重用、维护和测试;有效的利用资源,优化程序性能;保障进程安全和活性;减少性能损失和复杂度。
范式 | 体系 | 模块 | 模块关系 |
---|---|---|---|
过程式 | 君主体系 | 过程 | 授命与听命 |
函数式 | 数学体系 | 函数 | 替换与合成 |
逻辑式 | 逻辑体系 | 断言 | 归纳与演绎 |
对象式 | 民主体系 | 对象 | 交流与服务 |
并发式 | 生产体系 | 进程 | 竞争与合作 |
对象式和并发式在传统编程的基础上,分别从不同的方向进行拓展:对象式在数据类型上进行推广——允许运算作为数据类型的成员;并发式在执行顺序上进行推广——允许不同运算的执行在时间上交替或重合。