编程范式 | 青训营笔记

102 阅读10分钟

前言

本文适合对编程范式感兴趣的程序员或者正在学习编程的初学者阅读。在阅读本文前,读者应该具备一定的编程基础和逻辑思维能力。

总之,编程范式是一种重要的程序设计思想和方法,掌握不同的编程范式对于编写高质量的程序非常重要。本文将介绍不同的编程范式,帮助读者了解它们的基本思想和方法,为日后深入学习和应用打下坚实的基础。

编程语言

机器语言、汇编语言、中级语言、高级语言是计算机程序设计中的不同级别的语言,每种语言都有自己的特点适用场景

  • 机器语言:机器语言是计算机能够直接执行的语言,它由0和1组成的二进制代码表示各种指令和数据。机器语言是计算机底层的语言,对程序员来说不太友好,需要一定的汇编语言知识和计算机组成原理的基础。
  • 汇编语言:汇编语言是一种符号化的机器语言,用助记符号代替了机器语言的二进制代码,提高了编写程序的效率。汇编语言程序需要通过汇编器将汇编代码翻译成机器语言指令,才能被计算机执行。
  • 中级语言:中级语言是介于机器语言和高级语言之间的一种语言,它既比汇编语言高级一些,又比高级语言底层一些。中级语言可以通过编译器将程序翻译成机器语言,也可以通过解释器直接运行程序。面向过程代表的中级语言包括C语言等。
  • 高级语言:高级语言是一种接近人类语言的计算机程序设计语言,具有更高的抽象层次和更丰富的语法特性,能够更方便地表达程序设计思想和算法逻辑。高级语言包括面向对象代表的C++、函数式代表的Lisp、多范式代表的JavaScript等。

总之,机器语言、汇编语言、中级语言和高级语言是计算机程序设计中的不同级别的语言,每种语言都有自己的特点和适用场景。不同的语言可以根据需求和应用场景进行选择和使用。

面向过程问题

面向过程是一种程序设计思想,它将程序看作是一系列对数据的操作,强调数据和算法的紧密关联。面向过程的程序设计方式具有一些缺点,如下所述:

  • 数据与算法关联弱:在面向过程的程序设计中,数据和算法之间关联比较弱。数据和算法分别定义在不同的函数中,需要通过参数传递和返回值来进行数据的传递和处理。这样会导致程序的可读性和可维护性较差,不利于程序的设计和开发。
  • 不利于修改和扩充:在面向过程的程序设计中,程序的结构比较简单,主要由一系列函数组成。如果需要修改或扩充程序,就需要修改或添加相应的函数。这样会导致程序的耦合度较高,不利于程序的扩展和维护。
  • 不利于代码重复用:在面向过程的程序设计中,常常需要在多个函数中重复编写相同的代码,如输入输出、错误处理等。这样会导致程序的冗余度较高,不利于代码的重复使用和维护。

针对面向过程的这些缺点,一些新的程序设计思想和方法逐渐发展起来,如面向对象、函数式编程等。这些编程思想和方法可以更好地解决程序设计中的问题,提高程序的可读性、可维护性和可扩展性。

面向对象问题

面向对象编程语言的问题在于,它总是附带着所有它需要的隐含环境。你想要一个香蕉,但得到的却是一个大猩猩拿着香蕉,而且还有整个丛林。

针对面向对象的这些缺点,程序员可以采取一些方法和技巧来解决。例如,合理地设计对象和类,避免对象之间的耦合性太高;采用设计模式等技术,提高代码的可读性和可维护性;使用工具和框架,提高开发效率和代码的质量等。

总之,面向对象是一种重要的程序设计思想,它具有许多优点,但也存在一些缺点。程序员需要根据实际需求和项目情况选择合适的程序设计方式,合理地设计对象和类,提高代码的可读性、可维护性和可扩展性。

函数式编程优势

  • 可缓存:在函数式编程中,由于使用纯函数,同样的输入总是得到同样的输出,这使得结果可以进行缓存,提高程序的运行效率。
  • 可移植:函数式编程强调使用函数的组合来构建程序,这种组合方式具有可移植性,可以在不同的平台上运行。
  • 可测试:由于函数式编程使用纯函数,函数的输入和输出可以进行完全的隔离,不需要测试桩和模拟对象。这使得测试变得更容易,可以提高代码的质量和可靠性。
  • 可推理:函数式编程中的函数具有数学意义,可以使用代数运算和数学规则来简化和优化程序。这使得程序的逻辑更加清晰,易于推理和理解。
  • 可并行:函数式编程强调使用不可变数据和纯函数,这使得程序具有天然的并行性,可以方便地进行并行计算,提高程序的运行效率。

总之,函数式编程具有一些优势,如可缓存、可移植、可测试、可推理和可并行等。这些优势使得函数式编程在一些场景下比其他编程范式更加适用,例如数据处理、并行计算、并发编程等。

下面是函数式编程用到的一些技术。

  • first class function(头等函数) :这个技术可以让你的函数就像变量一样来使用。也就是说,你的函数可以像变量一样被创建、修改,并当成变量一样传递、返回,或是在函数中嵌套函数。
  • tail recursion optimization(尾递归优化) : 我们知道递归的害处,那就是如果递归很深的话,stack 受不了,并会导致性能大幅度下降。因此,我们使用尾递归优化技术——每次递归时都会重用 stack,这样能够提升性能。当然,这需要语言或编译器的支持。Python 就不支持。
  • map & reduce :这个技术不用多说了,函数式编程最常见的技术就是对一个集合做 Map 和 Reduce 操作。这比起过程式的语言来说,在代码上要更容易阅读。(传统过程式的语言需要使用 for/while 循环,然后在各种变量中把数据倒过来倒过去的)这个很像 C++ STL 中 foreach、find_if、count_if 等函数的玩法。
  • pipeline(管道):这个技术的意思是,将函数实例成一个一个的 action,然后将一组 action 放到一个数组或是列表中,再把数据传给这个 action list,数据就像一个 pipeline 一样顺序地被各个函数所操作,最终得到我们想要的结果。
  • recursing(递归) :递归最大的好处就简化代码,它可以把一个复杂的问题用很简单的代码描述出来。注意:递归的精髓是描述问题,而这正是函数式编程的精髓。
  • currying(柯里化) :将一个函数的多个参数分解成多个函数, 然后将函数多层封装起来,每层函数都返回一个函数去接收下一个参数,这可以简化函数的多个参数。在 C++ 中,这很像 STL 中的 bind1st 或是 bind2nd。
  • higher order function(高阶函数):所谓高阶函数就是函数当参数,把传入的函数做一个封装,然后返回这个封装函数。现象上就是函数传进传出,就像面向对象对象满天飞一样。这个技术用来做 Decorator 很不错。

函数式编程关注的是:describe what to do, rather than how to do it。于是,我们把以前的过程式编程范式叫做 Imperative Programming – 指令式编程,而把函数式编程范式叫做 Declarative Programming – 声明式编程。

函数式语言有三套件,Map、Reduce 和 Filter

编程本质和逻辑编程

image.png

编程本质是将问题抽象为计算机能够理解和执行的指令序列,通过编写程序实现问题的解决。编程语言是用来描述程序的算法和逻辑的工具,不同的编程语言有不同的语法、语义和编程范式。

逻辑编程是一种编程范式,它强调使用逻辑语句来描述程序的运算过程和结果,而不是使用具体的算法和数据结构。逻辑编程中的程序由一组事实和规则组成,程序员需要定义问题的逻辑关系,然后使用逻辑推理来求解问题。逻辑编程通常使用Prolog等语言进行实现。

  • Programs = Algorithms + Data Structures
  • Algorithm = Logic + Control

Program = Logic + Control + Data Structure

  • Control 是可以标准化的。比如:遍历数据、查找数据、多线程、并发、异步等,都是可以标准化的。
  • 因为 Control 需要处理数据,所以标准化 Control,需要标准化 Data Structure,我们可以通过泛型编程来解决这个事。
  • 而 Control 还要处理用户的业务逻辑,即 Logic。所以,我们可以通过标准化接口 / 协议来实现,我们的 Control 模式可以适配于任何的 Logic。

上述三点,就是编程范式的本质。

有效地分离 Logic、Control 和 Data 是写出好程序的关键所在

总之,编程本质是将问题抽象为计算机能够理解和执行的指令序列,逻辑编程是一种编程范式,强调使用逻辑语句来描述程序的运算过程和结果。逻辑编程具有一些优点,如简洁、清晰和易于理解等,也有一些缺点,需要根据具体的问题和需求进行选择和应用。

结语

如果你觉得此文对你有一丁点帮助,点个赞,鼓励一下小陈哈哈。

宝贝们,都看到这里了,要不点个赞呗 👍🏻

写作不易,希望可以获得你的一个「赞」。如果文章对你有用,可以选择「关注 + 收藏」。 如有文章有错误或建议,欢迎评论指正,谢谢你。❤️