13 | 结构化编程:为什么做设计时仅有结构化编程是不够的?
- 深入了解
- 翻译
- 解释
- 总结
结构化编程是编程范式中的重要一环,它的发展历程和对编程的影响不容忽视。文章首先从汇编语言的控制结构出发,解释了结构化编程的由来,并指出了非结构化编程的挑战。随后,文章介绍了迪杰斯特拉提出的“Go To Statement Considered Harmful”理论,以及对结构化编程的争议和发展。最终,文章指出了结构化编程的重要性和影响,以及现代程序设计语言对goto语句的处理方式。通过这些内容,读者可以了解到结构化编程的起源、发展和对编程的影响,以及其在现代编程语言中的地位。 文章深入探讨了结构化编程的核心思想,强调了功能分解的重要性,以及其对软件开发产生的深远影响。结构化编程的优势在于将大问题拆解成一系列可证明的小问题,但随着程序规模的膨胀,其抽象级别不足以满足需求变化,导致程序组织方式显得僵硬,缺乏有效隔离变化的能力。因此,结构化编程需要与其他编程范式结合,以应对日益膨胀的软件规模。 总的来说,结构化编程为程序员提供了重要的编程元素,但也限制了程序的灵活性和可测试性。读者通过本文可以深入了解结构化编程的发展历程和局限性,以及其与其他编程范式的关系,为进一步学习和应用编程范式提供了重要的参考。
《软件设计之美》,新⼈⾸单¥59
全部留言(16)
- 最新
- 精选
- escray看了一下 Edgar Dijkstra 的那篇 Go To Statement Considered Harmful,其中说到,go to statements should be abolished from all “higer level” programming languages. 论文里面提到两个 remark,一个是说一旦程序被编写完成,那么程序的控制权就交给了机器;第二个是说,程序员(人)对于静态关系掌控和动态过程视觉化都有一定的局限,所以要尽量减少静态程序代码和动态过程的“认知鸿沟”。 专栏里面提到了“非结构化编程”,结合 Dijkstra 的论文,感觉使用 go to 语句的非结构化编程更像是一种“线性编程”,在一个很长的代码文件上给出了几个索引(标签),然后使用 go to 语句来跳转。如果不怕重复,把所有的 go to 都展开,那么应该就是更长的一段代码。 而使用了 if/else、do/while 的结构化编程,感觉是把一条线变成了一棵树,从一维坐标到二维坐标(?)。从认知的角度,更有利于程序员去开发程序——其实也就是前面 Dijkstra 说的,程序的复杂度超出了程序员的控制,所以需要结构化编程来降低认知的难度。 1969 年阿波罗 11 号登月的时候,使用的编程语言应该是汇编吧,即没有结构化也没有面向对象。后来看到了左耳朵耗子在酷壳上的一片文章《50年前的登月程序和程序员有多硬核》,确实 hardcore。 最早学的也是 C 语言,然后学到面向对象的时候(C#)的时候,看到那些小猫小狗、继承多态的例子,感觉也很震撼,后来才发现在实际的工作中,面向对象的分析并不简单,面向对象的落地也不容易。
作者回复: 理解是一个难度,设计是一个难度,所以,Dijkstra能拿到图灵奖。
2020-06-2421 - Jxin1.结构化编程/过程式编程,感觉栏主漏了一个很重要的点,贫血模型。结构化编程里面有结构体(自定义的类型)的概念,站java角度看,这其实这就是一个"类",但这个类只承接属性却不会有行为。也就是说过程式编程里面,行为和数据是完全分离的(我不认为这是坏处,毕竟这样代码实现和阅读都相对简单)。并且结合对过程的抽象(这里应该算得上函数了),可以定义各种复杂的指令,以便达到复用和隔离复杂性的效果。(这些特性也是导致大部分开发都面向过程编程的主要原因) 2.既然结构化编程能做到复用和隔离复杂性,那么还要面向对象干嘛?或者说面向对象相较于结构化编程优秀在哪里?我认为至少有两点优秀的地方,1.易用 2.更好的复杂性隔离。易用,某种带有数据结构的"类",其具备哪些行为一目了然(打点可见)。而不像过程式编程,数据与过程的关系是松散的(java开发可以理解为所有代码都以静态方法+贫血模型实现);更好的复杂性隔离,这主要依托于面向对象的一个特性,封装。面向对象不主张绕过对象的使用接口侵入到对象的内部实现细节,如此一来对象内部的变动与所有使用方就隔离了,换句话说,只有在对象内部才能变更对象的属性,变更点全部收敛。(封装其实是一种约束,让代码没办法那么灵活。但这个约束对于代码的可读和可维护却有着深远的价值) 3.学习ddd让我受到了很大的震撼。起初,我看了一遍领域驱动设计实战那本号称比较好理解的“红皮佳作”。然并软,看了一遍基本不理解各中缘由,也就拿着专业名称跟别人瞎应付几句,表示自己也学过。但后来,深入去学习设计原则与设计模式,面向对象思想,并做了大量的重构(期间经常会翻到“红皮佳作”的某些章节思考)。对于ddd为啥这么做有了自己的见解。1.为什么依赖倒置,基础层要在最上层。因为这样做技术相关代码可以从应用层和领域层抽离,保证应用层和领域层业务代码的干净(技术组件可以单独升级)。 2.为什么要封装充血模型?为了更好的复用以及隔离复杂性. 3.为什么要分应用层和领域层?将基础的领域服务代码和上层的应用服务代码隔离,将不同的领域服务代码相隔离,将不同的应用服务代码相隔离。做到,虽然将多个模型(基础模型和应用模型)写在一个包里,但以目录和编程规范的方式将之间的代码隔离,为后续业务拓展后的调整铺平道路。(也包含去重的理念)4.为什么要制定规范,为什么要抽象系统模型图? 为了降低认知差异(同规范下,相互间代码可读性自然会更好),提高共识度(没办法产品技术一体两面,就在业务逻辑和代码实现间再架设一层中间语言,方便两者沟通。是不是有点IR“高级语言与机器语言的中间表达式”的味道)。等等。。。
作者回复: 我还真的不把贫血模型的讨论放在结构化编程里,它更多的属于 OO 部分。 你的 DDD 理解很有道理,但有一些内容其实属于 OO,比如依赖倒置,后面会讲到。
2020-06-24214 - 西西弗与卡夫卡刚开始接触函数式编程时,就被它背后的数学理论所震到,之前一直把计算机看成是工程学。后来看到它的不变性天生适合并发时,又深深体会到它的美感
作者回复: 震撼的感觉是非常爽的,让人找到了新的前进方向。
2020-06-2411 - hello zero在学习机器学习和深度学习编程的过程中,被其背后的数学思想所震撼,这是第一次觉得数学离编程这么近且不可或缺。
作者回复: 机器学习和深度学习,终于让数学走近了程序员。
2020-06-296 - Hank_Yan布隆过滤器,hyperloglog,这些基于统计思想设计的算法,着实把我镇住了,数学真重要!
作者回复: 这个例子非常棒!这确实是超出普通程序员理解的东西,能给思想带来极大冲击。
2020-11-234 - 青鸟飞鱼之前看设计模式中提到面向过程与面向对象,让我产生了困惑;写类成员函数时,可它的实现我用的明明是面向过程,让我产生了困惑。读了今天的课程,解决了我的困惑。
作者回复: 进一步则喜,恭喜你!
2020-07-1722 - 学要有所用汇编的goto特性使得编程不可控,不受约束,为了约束编程行为,结构式编程应运而生,其自上而下的编程方法使得程序易于编写和理解,但由于自上而下,每行代码紧密相连,下层代码的运行依赖于上层代码,耦合度太高,约束性太强,一旦代码变动,所有相关连的代码可能都得变动,灵活度太低,于是面向对象编程横空出世,就拿java来说,其强大的语言特性使得代码灵活性大大提高,与汇编的goto特性相比,java的if else ,for循环等对程序的行为起到了约束作用,这些结构类代码将原本不受约束的代码行为控制在了结构代码内,它的各种访问修饰符所带来的封装特性对代码的行为也起到了约束作用,同时也一定程度提高了代码的安全性。继承特性的出现使得重复使用的代码变得可复用,减少了大量冗余代码,还能在继承之外添加自己的功能行为,多态的出现在继承的基础上进一步加强了这一行为,使代码的灵活性更高。为了进一步增强代码的灵活性,反射机制出现了,与结构化编程的按步骤执行不同,它能在代码的运行阶段操控代码,可以说,面向对象的编程范式通过对象模型的映射,配合其特性,极大地提高了代码的灵活性,减少了大量冗余的代码。不知道以上理解对不对?
作者回复: 大部分理解是对的,但是,继承,我们很快就会说到,到时候,你再来看。
2020-06-242 - chenzesamflutter 一切皆 widget 的思考,远大于我们能看见的表面。
作者回复: 很好的分享!
2020-06-242 - 阳仔相信很多人一开始学习c编程语言入门的,这时教材上会告诉这是结构化编程编程语言。 学习了体系结构和汇编相关知识之后,会发现底层语言是非结构化的, 这给编码效率带来不便,于是出现结构化编程,也出现了更高层次的分层与封装。 结构化编程符合人类的思维。当我们开发系统时,分解各个小系统,小系统分解成模块,模块分解为组件,组件分解类,类分解为功能函数。 一步一步下来,完成整体的功能拆分。 当然结构化编程不是银弹,它也有缺点,比如高层依赖底层模块强,不容易测试等,这些需要其它编程范式一起解决
作者回复: 结构化何止不是银弹,现在作为普通的工具,能力都是不够的。简言之,现在打仗不能只靠弓箭和马匹了,而结构化编程大概就是这么个级别的东西,冷兵器时代的产物。
2020-06-242 - sam初学编程的人都习惯所谓“面条型”代码,就是结构化编程吧^_^
作者回复: 如果来吐槽的话,确实是这样的。
2020-06-241