天天看点

编程范式(一):结构化编程

大家好,我是寒草????,一只工作一年半的草系码猿????

如果喜欢我的文章,可以关注 ➕ 点赞,与我一同成长吧~

一起学习交流,成为更优秀的工程师~

总览

上一篇文章: ​​寒草与《架构整洁之道》|树叶飞舞,故事开始????​​简要介绍了什么是设计与架构,以及架构的价值所在,本篇文章将介绍编程范式。

编程范式指的是程序的编写模式,与具体的编程语言关系相对较小。这些范式会告诉你应该在什么时候采用什么样的代码结构。直到今天,我们也一共只有三个编程范式:

  • 结构化编程
结构化编程对程序控制权的直接转移进行了限制和规范。Dijkstra 论证了使用 goto 这样的无限制跳转语句将会损害程序的整体结构,也是这位 Dijkstra 最先主张用我们现在熟知的 if/then/else 语句和 do/while/until 语句来代替跳转语句的。
  • 面向对象编程
面向对象编程对程序控制权的间接转移进行了限制和规范。
  • 函数式编程
函数式编程对程序中的赋值进行了限制和规范。

这三个编程范式都从某一方面限制和规范了程序员的能力。没有一个范式是增加新能力的。也就是说,每个编程范式的目的都是设置限制。这些范式主要是为了告诉我们不能做什么,而不是可以做什么。

另外,我们应该认识到,这三个编程范式分别限制了 goto 语句、函数指针和赋值语句的使用。

结构化编程

可推导性

编程是一项难度很大的活动。一段程序无论复杂与否,都包含了很多的细节信息。如果没有工具的帮助,这些细节的信息是远远超过一个程序员的认知能力范围的。而在一段程序中,哪怕仅仅是一个小细节的错误, 也会造成整个程序出错。

对于上面的问题,Dijkstra 提出的解决方案是采用数学推导方法。即:程序员可以用代码将一些己证明可用的结构串联起来,只要自行证明这些额外代码是正确的,就可以推导出整个程序的正确性。

Dijkstra 在研究过程中发现了一个问题: goto 语句的某些用法会导致某个模块无法被递归拆分成更小的、可证明的单元,这会导致无法采用分解法来将大型问题进一步拆分成更小的、可证明的部分。

goto 语句的其他用法虽然不会导致这种问题,但是 Dijkstra 意识到它们的实际 效果其实和更简单的分支结构 if-then-else 以及循环结构 do-while 是一致的 。 如果代码中只采用了这两类控制结构,则一定可以将程序分解成更小的、可证明的单元。

Bohm 和 Jocopini 证明了人们可以用顺序结构、分支结构、循环结构这三种结构构造出任何程序。这个发现非常重要: 因为它证明了我们构建可推导模块所需要的控制结构集与构建所有程序所需的控制结构集的最小集是等同的。 这样一来,结构化编程就诞生了。

科普一下:​

​顺序结构和分支结构的正确性可以用枚举法证明,但是循环结构需要采用**数学归纳法**:具体来说就是,首先要用枚举法证明循环 1 次的正确性,接下来再证明如果循环 N 次是正确的,那么循环 N+1 次也同样也是正确的。​

GOTO 是有害的

这是一段有趣的故事:

1968 年,Dijkstra 曾经给 CACM 的编辑写过一封信 。 这封信后来发表于 CACM 3 月刊,标题是 Go To Statement Considered Harmfu/1, Dijkstra 在信中具体描绘了他对三种控制结构的看法。

由于当时还没有互联网,大家还不能直接上网发帖来对 Dijkstra 进行冷嘲热讽,他们唯一能做的,也是大部分人的选择,就是不停地给各种公开发表的报刊的编辑们写信。

有的信件的措辞并不那么友善,甚至是非常负面的。但是,也不乏强烈支持者。总之,这场火热的争论持续了超过 10 年 。

中间吐槽一句:​

​这一幕像极了现在网上的各种骂战,哈哈哈​

这场辩论最终还是逐渐停止了。原因很简单: Dijkstra是对的。随着编程语言的演进,goto 语句的重要性越来越小,最终甚至消失了。如今大部分的现代编程语言中都己经没有了 goto 语句。

现如今,无论是否自愿,我们都是结构化编程范式的践行者了,因为我们用的编程语言基本上都己经禁止了不受限制的直接控制转移语句。

功能性降解拆分

既然结构化编程范式可将模块递归降解拆分为可推导的单元,这就意味着模块也可以按功能进行降解拆分。这样一来,我们就可以将一个大型问题拆分为一系列高级函数的组合,而这些高级函数各自又可以继续被拆分为一系列低级函数,如此无限递归。更重要的是,每个被拆分出来的函数也都可以用结构化编程范式来书写。

通过采用这些技巧,程序员可以将大型系统设计拆分成模块和组件,而这些模块和组件最终可以拆分为更小的、可证明的函数。
编程范式(一):结构化编程

其中思想至今仍被沿用????

结束语

编程范式(一):结构化编程

结构化编程范式中最有价值的地方就是,它赋予了我们创造可证伪程序单元的能力。这就是为什么现代编程语言一般不支持无限制的 goto 语句。更重要的是,这也是为什么在架构设计领域,功能性降解拆分仍然是最佳实践之一。

最后还有一句话印象深刻:一段程序可以由一个测试来证明其错误性,但是却不能被证明是正确的。

✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨

少年向来不识天高地厚

放眼处皆自负才高八斗

虽是自命风流

倒也坦诚无忧

我爱这样的少年

谦和而狂妄

骄傲又坦然☀️

继续阅读