编程范式

46 阅读3分钟

范式指解决问题的方法,编程范式指用程序语言解决问题的方式。
整体上编程范式分为两个阵营:命令式 (imperative) V.S. 声明式 (declarative)。

1 命令式

命令式编程起源早,基于冯诺依曼结构,包含指令和指令的存储,通过控制状态来达成目标,核心是指令顺序。
包括 3 种常见编程范式:面向过程范式 OPP(Procedure Oriented Programming),面向对象范式 OOP(Object Oriented Programming),并行计算范式 (Parallel Processing Approach)

  • 面向过程式强调在机器结构基础上描述执行过程,核心优势是过程的复用。典型语言:C/C++/JAVA/Pascal
int[] nums = new int[]{1,2,5,3,8};
int[] result = new int[nums.length];
int curidx = 0;
for (int num : nums) {
    if (num > 5) {
        result[curidx++] = num;
    }
}
return result;

实现了从一个数组中检索大于 5 的数,过程是先构建一个返回数组,遍历当前数组中每个值,如果符合条件则添加到返回数组中。

  • 面向对象式强调基于问题抽象出对象,定义类和他们之间的关系,关注数据而不是过程。典型语言:JAVA/C++/Objective-C/VB/Python/Ruby
class Person {
   private int age;
   private String name;
}

class Employee implements Person {
   private float salary;
}

人定义了年龄和名字两个属性,打工人是人的继承,不用再定义人拥有的属性,额外扩展了打工人的薪资。

  • 并行计算式强调多核的指令拆分和协作。典型语言:NESL,C/C++(一部分库函数支持并行计算)
function qsort(a) =
if (#a < 2) then a
else
  let pivot   = a[#a/2];
      lesser  = {e in a| e < pivot};
      equal   = {e in a| e == pivot};
      greater = {e in a| e > pivot};
      result  = {qsort(v): v in [lesser,greater]};
  in result[0] ++ equal ++ result[1] $

通过语言的并行计算能力,实现了快速排序。

2 声明式

声明式编程描述完成任务的计算逻辑而不关注控制流程,开发者的角色从思考如何完成计算转换到什么需要计算。
包括 3 种常见编程范式:逻辑范式 (Logic Programming),函数式范式 (Functional Programming) ,数据驱动范式 (Database Processing Approach)

  • 逻辑式强调问题的知识基础,机器学习很多也是基于逻辑范式。典型语言:Prolog
likes(bell,sports).         
likes(mary,music).
likes(mary,sports).
likes(jane,smith).

friend(john,X):-            
        likes(X,sports),
        likes(X,music).

第一段 likes() 引导的部分是知识基础,表达某个人喜欢什么。第二段定义 john 对朋友的要求,喜欢 sports 和 music。此时如果询问 friend(john,X) 即 john 的朋友是谁?会得到回答:marry,因为 john 对朋友的要求 marry 最匹配。这也是一段简单的机器学习逻辑,人工智能本质上在做的是类似这样的逻辑范式编程。

  • 函数式植根于数学,且与语言强相关,强调执行一组数学函数的流程。主旨是将计算过程和数据解耦,用函数来封装细节实现。典型语言:JavaScript/Perl
def get_users(age: int) -> list:
    ret = []
    for user in users:
        if user['age'] > age:
            ret.append(user)
    return ret

函数实现了筛选年龄大于输入值的所有用户。

  • 数据驱动式基于数据和其流转。典型语言:SQL
SELECT *
FROM users
where phone like '135%';

查询所有手机号以 135 开头的用户。

总结

编程范式分为两个阵营,命令式编程关心如何计算 how,声明式编程关心计算什么 what。不同的编程范式不是泾渭分明的,往往某种语言的实现会同时用到多种范式,例如 JAVA 以命令式的面向对象为主,掺杂面向过程、函数式等其他编程范式。
重要的不是区分不同的编程范式,而是灵活的应用编程范式在具体的场景下高效的解决问题。