ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ### 面向对象编程(OOP)与面向函数编程(FOP) #### **面向对象编程(OOP)** **在OOP中,一切皆是对象**。 在面向对象的命令式(imperative)编程语言里面,构建整个世界的基础是类和类之间沟通用的消息,这些都可以用类图(class diagram)来表述。《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software,作者ErichGamma、RichardHelm、Ralph Johnson、John Vlissides)一书中,在每一个模式的说明里都附上了至少一幅类图。 **OOP 的世界提倡开发者针对具体问题建立专门的数据结构,相关的专门操作行为以“方法”的形式附加在数据结构上,自顶向下地来构建其编程世界**。 **OOP追求的是万事万物皆对象的理念,自然地弱化了函数**。例如:函数无法作为普通数据那样来传递(OOP在函数指针上的约束),所以在OOP中有各种各样的、五花八门的设计模式。 绝大部分设计模式的实现都离不开多态性的思想。换一种说法就是,这些设计模式背后的本质其实就是OOP的多态性,而OOP中的多态本质上又是受约束的函数指针。 很多设计模式,在函数式编程中都可以用高阶函数来代替实现: ![](https://box.kancloud.cn/e2b15f5226dba8343e9481226823ffcb_1001x514.png) #### **面向函数编程(FOP)** 在FP中,一切皆是函数。 函数式编程(FP)是关于不变性和函数组合的一种编程范式。 **函数式编程语言实现重用的思路很不一样。函数式语言提倡在有限的几种关键数据结构(如list、set、map)上 , 运用函数的组合 ( 高阶函数) 操作,自底向上地来构建世界。** 当然,我们在工程实践中,是不能极端地追求纯函数式的编程的。一个简单的原因就是:性能和效 率。纯函数式编程是解决某些问题的伟大工具,但是在另外的一些问题场景中,并不适用。因为副作用总是真实存在。 **OOP喜欢自顶向下架构层层分解(解构),FP喜欢自底向上层层组合(复合)**。 而实际上,**编程的本质就是次化分解与复合的过程。通过这样的过程,创造一个美妙的逻辑之塔世界**。 在OOP中,一个理想的对象应该是只暴露它的抽象接口(纯表面, 无体积),其方法则扮演箭头的角色。如果为了理解一个对象如何与其他对象进行复合,当你发现不得不深入挖掘对象的实现之 时,此时你所用的编程范式的原本优势就荡然无存了。 FP通过函数组合来构造其逻辑系统。FP倾向于把软件分解为其需要执行的行为或操作,而且通常采用自底向上的方法。函数式编程也提供了非常强大的对事物进行抽象和组合的能力。 在FP里面,函数是“一类公民”(first-class)。它们可以像1, 2, "hello",true,对象…… 之类的“值”一样,在任意位置诞生,通过变量,参数和数据结构传递到其它地方,可以在任何位置被调用。 而在OOP中,很多所谓面向对象设计模式(design pattern),都是因为面向对象语言没有firstclass function(对应的是多态性),所以导致了每个函数必须被包在一个对象里面(受约束的函数指针)才能传递到其它地方。 #### **匀称的数据结构 + 匀称的算法** ***** 程序 = 匀称的数据结构 + 匀称的算法 ***** 如图所示 ![](https://box.kancloud.cn/15efa194e772d2bf57ee1dc990972d59_1071x1070.png) 我们在编程中,不可能使用纯的对象(对象的行为方法其实就是函数),或者纯的函数(调用函数的对象、函数操作的数据其实就是数据结构)来创造一个完整的世界。如果 数据结构是阴 , 算法是阳 ,那么在解决实际问题中,往往是阴阳交合而成世界。 真实的编程世界,自然是匀称的数据结构结合匀称的算法(SDS-SA)来创造的。 **函数与映射** 一切皆是映射。函数式编程的代码主要就是“对映射的描述”。我们说组合是编程的本质,其实,组合就是建立映射关系。 一个函数无非就是从输入到输出的映射,写成数学表达式就是: ``` f: X -> Y p:Y -> Z p(f) : X ->Z ``` 用编程语言表达就是: ~~~ fun f(x:X) : Y{} fun p(y:Y) : Z{} fun fp(f: (X)->Y, p: (Y)->Z) : Z { return {x -> p(f(x))} } ~~~