什么是编程范式

编程范式(Programming parading),即编程的模式、方法,指编程风格。

编程范式是编程语言的一种分类,并不针对某种编程语言。

一种编程语言可以适用多种编程范式

一些编程语言是为某种特定的编程范式设计的:

  • C语言是过程式编程(面向过程编程)语言
  • Java、Smalltalk是较纯粹的面向对象编程语言
  • Haskell是纯粹的函数式编程语言

一些编程语言与编程范式没有固定的一一对应关系:

  • Python,Scala,Groovy支持面向对象编程及一定程度的函数式编程
  • C++是多范式编程语言,它是面向过程编程语言,同时支持面向对象编程,STL使C++具有了泛型编程能力
  • Swifthi多范式编程语言,支持面向对象编程函数式编程范型编程

常见编程范式

不同编程语言偏爱不同的编程范式:

  1. 面向过程编程(命令式编程)
  2. 面向对象编程
  3. 函数式编程
  4. 范型编程

不论用哪种编码方式,都是为了写出更通用,可复用,更具有重用性的代码或模块。

面向过程编程(命令式编程)

也称为‘命令式编程’,是一种最原始,日常工作中使用较多的一种编程范式。

面向过程的核心即将问题分解,将解决步骤分析出来,然后按步骤一步一步解决问题。

面向过程编程是一种直观的编程方式,更符合我们日常的思维方式。

用于计算机语言中,面向过程编程,更关注计算机的执行步骤,即一步步告诉计算机应该做什么。

优缺点

优点

  • 面向过程编程,思维方式简单,利用程序流程图能够清晰的完成编码思路
  • 面向过程编程,适合解决线性问题,强调自上而下、精益请求的设计方式
  • 底层灵活且高效,适合开发运行较快、系统资源利用率要求较高的程序

缺点

  • 不适合解决某些种类问题。(如:非结构的具有复杂算的问题)
  • 当项目庞大、逻辑复杂时,会面临命名冲突、代码重复冗余的问题,不利于代码的可读性及可维护性。

流程驱动编程

主动轮询,行为取决于自身的判断,是流程驱动的

事件驱动编程

被动等通知,行为取决于外界事件,是事件驱动的

面向对象编程

面向对象编程(Object-oriented programming,简称OOP),是通过方法对象消息传递来支持面向对象的编程范式。

(消息传递:一个对象调用了另一个对象的方法)

(对象指类的实例)

将数据和方法封装在对象中,对象中的方法可以访问及修改对象中的数据,提高代码的复用性、灵活性、可拓展性。

面向对象编程的特性

封装

封装为两个过程:

​ 将数据和操作(方法)捆绑在一起,创造出一个新的类型的过程。

​ 将接口与实现分离的过程。

通过封装,使软件结构相关部件实现“高内聚,低耦合”,这是封装性所需要的基本目标。

对用户来说,不需要了解程序的内部实现细节,只需要通过接口调用程序。

继承

一个类共享了一个或多个其他类定义的方法和属性。

子类可以对基类的行为(方法)进行扩展、覆盖、重定义,子类会比基类更为具体化。

多态

由于继承产生的多个相关但不同的类。

多个类在接收到完全相同的消息时,会产生不同的响应。

名词解释

  1. :相似对象的集合,定义了一件事物的抽象特点。

  2. 动态绑定:也称动态类型,指一个对象或者表达式的类型在运行时才确定。通常由编译器插入特殊代码实现。

  3. 静态绑定:也称静态类型,指一个对象或者表达式的类型在编译时确定。

  4. 消息传递:一个对象调用了另一个对象的方法。

  5. 方法:也称成员函数,指对象上的操作。方法定义了可以对对象执行的操作。

优缺点

优点

  • 数据抽象概念可以在保持外部接口不变的情况下,改变内部实现,从而减少对外部的干扰。
  • 通过继承机制,可以减少冗余代码,方便拓展现有代码。提高编程效率,降低代码维护成本。

缺点

  • 运行效率低:类的大量加载会牺牲系统性能,降低运行效率。
  • 类库庞大:由于类库庞大,需要一定学习成本。
  • 类库可靠性:无法保证类库中每个类在各个环境中百分百正确。

函数式编程

函数式编程(Function programming,简称FP),又称函数式程序设计、泛函编程。

函数式编程具体学习看这里

函数式编程将计算机运算视为函数运算,并且避免使用程序状态以及易变对象。

λ演算(lambda calculus)是函数式编程最重要的基础。λ演算的函数可以接受函数作为输入和输出。

函数式编程关心类型之间的关系,即输入类型和输出类型之间的关系。

λ演算就是给λ表达式一个输入类型的值,得到一个输出类型的值。

函数式编程更加强调程序的执行结果,而非执行过程。倡导利用简单的执行单元,逐层推导复杂的运算,而非设计一个复杂的执行过程。

函数式编程时面向数学的抽象,将计算描述为一种表达式求值,函数式程序就是一个表达式。

在函数式编程中,函数可以出现在任何位置。可以把函数作为参数传递给另外一个函数,函数也可以作为另外一个函数的返回值。

函数式编程的本质

  1. 函数式编程中的函数并非计算机中的函数,而是指数学中的函数,是指一种映射。函数的输出值取决于函数的输入值,不依赖于其他状态。

  2. 在函数式语言中,函数作为一等公民,可以在任何地方定义、使用。

  3. 函数式编程中的变量并非编程语言中的变量。

    编程语言中的变量指存储单元。

    函数式编程中的变量指值的名称

  4. 函数式语言的条件语句、循环语句也不是命令式编程语言中的控制语句,而是函数的语法糖。

  5. 函数式编程意味着,不使用可变的变量、赋值、循环和其他命令式控制结构进行编程。

  6. 理论上,函数式语言不是通过冯·诺依曼体系结构的机器运行的,而是通过λ演算来运行。

    但是大多数情况下,函数式程序还是被编译成机器语言执行指令。

函数式编程的特性

  1. 函数是一等公民(First-class Function)

    函数优先,函数可以在任何地方定义、使用。

  2. 只使用表达式

    通过表达式计算过程得到返回值,而非通过语句修改状态

  3. 无副作用

    不污染变量,相同输入永远得到相同输出

  4. 不可变性

    变量值不可变。

    对值的操作并不是修改原来的值,而是产生新的值,原来的值保持不变。

    纯函数编程语言无法实现循环。

    ​ For循环使用可变状态作为计数器。

    ​ While循环使用可变状态作为循环及跳出循环条件。

    函数式编程使用递归解决迭代问题,故函数式编程严重依赖递归

  5. 高阶函数(Higher-order function)

    即参数为函数或返回值为函数的函数。—-将复用的粒度降低到函数级别。

  6. 偏应用函数(Partially Applied Functions)

    一个函数接收一个有多个参数的函数,返回一个需要较少参数的函数。

    偏函数将一到多个参数在内部固定,然后返回新函数,返回的函数接收剩下的参数完成函数的应用

  7. 柯里化(Currying)

    输入一个有多个参数的函数,返回一个只接受一个参数的函数

  8. 闭包(Closure)

    引用了自由变量(不属于当前函数作用域的变量)的函数。

    特性:

    1. 闭包是定义在函数中的函数

      1. 闭包能访问外部函数中的变量
      2. 外部函数执行完毕后,被闭包引用的变量不会被释放。

优缺点

优点

  1. 引用透明,没有副作用

    因为函数式编程变量的不可变性

  2. 不易出错,易于单元测试及调试

    因为函数式编程的无副作用,不影响外部环境,不依赖外部环境,相同输入永远有相同输出。

  3. 更好的处理并发

    多个线程不共享状态,不争夺资源,不需要锁保护可变状态,不会出现死锁。

  4. 无this指向问题

  5. 惰性求值,提升性能

    将表达式赋值给变量时不做计算,变量第一次被使用时才做计算。避免不必要的求值,提升性能。

  6. 模式匹配

    可以定义代数数据类型,通过组合已有数据类型形成新的数据类型。代数数据类型的值可以通过模式匹配进行分析。

参考文章

  1. https://www.zhoulujun.cn/html/theory/engineering/model/8139.html