编程领域的范式转移

范式转移(Paradigm shift),这个名词最早出现于美国科学哲学家托马斯·库恩的代表作之一《科学革命的结构》。库恩认为范式是指特定的科学共同体从事某一类科学活动所必须遵循的公认的模式,它包括共有的世界观、基本理论、范例、方法、标准等等与科学研究有关的所有东西。每一项科学研究的重大突破,几乎都是先打破道统,打破旧思惟,而后才成功的,也就是所谓的范式转移。

范式转移后来也被引申为打破旧的思维框架。@硅谷王川老师在《范式转移的随想》中提到,

范式转移, 往往意味着完全不同的商业模式, 因为整个时间空间内的玩家,和他们彼此之间的关系全都彻底变了。但大部分人思考的惯性,是拿以前的模式去套用,因而始终不得要领。

商界有太多经典的案例,柯达和诺基亚因旧范式而死,苹果和亚马逊因新范式而生。

编程范式

计算机领域有编程范式( Programming paradigm)的概念,它代表着计算机领域的世界观和方法论,决定了程序员如何去分析和解决问题,如何认识程序的结构、交互和执行。除了我们熟悉的结构化编程、面向对象编程和函数式编程,常见的编程范式还有声明式编程、事件驱动编程、面向切面编程等。在维基百科的词条上,可以找到海量编程范型分类。

编程范式往往和编程语言本身强相关,需要用具体的编程语言来体现,编程语言在设计时都会倾向于承载一种或多种编程范式。

Programming paradigms for dummies: what every programmer should know, Peter Van Roy, 2009

设计原则

另一个大家更为熟悉的概念——设计原则,同样也能够决定分析和解决问题的思路。

设计原则关注代码与代码之间的交互设计,强调解决“职责”、“依赖”和“变化”的问题。设计原则这个概念本身并没有一个统一的定义,可以理解为代码设计方法论的统称。GRASP原则、SOLID原则和23种设计模式等大约都属于该范畴。

编程范式是一种客观上的强约束条件,如果用一种语言去开发,就必然要遵循这种语言所属的编程范式。用C语言进行函数式编程、用Java进行逻辑式编程,必然处处受到掣肘,甚至无法执行。而设计原则是主观上的弱约束条件,每个人都在依照自己对原则的理解去实现代码,而且即使不采用任何原则,仍然可以写出运行无误的代码。

很明显,范式是“道”,原则是“法”。相比之下,开发规约这玩意只能算“术”。

编程范式影响设计原则

许多设计模式都是为了克服面向对象编程范式的一些缺陷或局限而设计的,但是当范式发生转移,这些缺陷或局限不复存在,所以设计模式也就无用武之地了。

比如观察者模式、中介者模式为了克服对象通信上信息发送者和信息接收者的耦合,但事件驱动式编程范式是天生支持的;如命令模式是为了克服命令请求者和执行者之间的耦合,但在函数式编程中函数是头等公民,可以将命令或请求封装为一个函数来轻松解决这个问题。

编程范式影响算法实现

有时候同样的算法,用不同的编程范式去实现,思维模式有很大差别,开发成本和可维护性根本不在一个量级。

以徒手写快排为例,如果用过程式双指针方法来实现,至少花费了我20分钟(手有点生),还不保证完全可用,因为一些边界条件还没有测试到:

而用函数式实现一个基本可用的版本,大概只用了5分钟。函数式编程的“无副作用”,带来了极强的可读性:

现代编程语言一直在进化,会不断有原生特性或者第三方框架来支持多种范式。范式转移有时候比固有思维的复杂解决方案更值得研究。故程序之法,上者谋范式,其次取原则,最次学规约。