Skip to main content
 首页 » 操作系统 » linux系统

函数式编程(Functional Programming)相比面向对象编程(Object-oriented Programming)有哪些优缺点?

面向对象和函数式编程主要是抽象方式的区别,抽象方式的不同导致了优缺点的不同。

抽象方式面向对象将现实抽象为一个个的对象,以及对象间的通信来解决问题。

函数式编程将现实抽象为有限的数据结构,以及一个个的对这些数据结构进行操作的函数,通过函数对数据结构的操作,以及函数间的调用来解决问题。

对象也是一种数据结构,面向对象实际是将现实抽象为了无数个具有有限操作的数据结构。

反过来函数式编程是将现实抽象为具有无数个操作的有限个数据结构。

两者的优缺点就很明显,面向对象可以很方便的增加类型,却很难在不修改已定义代码的前提下,为既有具体类实现一套既有的抽象方法(称为表达式问题)。而函数式编程可以很方便的增加操作,但很难新增一个适应各种既有操作的类型。

比如Java里的字符串本身没有capitalize方法,理想的方法应该是“abc”.capitalize(),但是Java里需要Util类来实现。虽然ruby可以通过猴子补丁实现,scala可以通过隐式转换实现,kotlin可以通过intern方法实现,但是实际上是通过各种手段弥补这个缺陷。

对于函数式语言来说,比如jvm上的lisp语言Clojure,它的集合都实现了n多个接口:Collection,Sequence,Associative,Indexed,Stack,Set,Sorted。使得一组函数可以应用到set,list,vector,map。如果要新增一个数据结构,就需要实现n多的方法。

不可变性另外一个抽象方式的区别就是不可变性和可变性。这个很多地方有讲,就不细聊了。

函数式编程强调不可变性,所以易于支持并发编程,但对于状态的修改就需要特殊处理。面向对象编程则反之,状态想怎么变就怎么变,所以并发编程需要加各种锁。

抽象程度抽象方式的不同,间接导致了抽象程度的不同。

函数式编程的抽象程度要高于面向对象,因为最终都是抽象为那几个数据结构。而面向对象可以构建贴近现实的数据对象。

抽象度越高,也就越难理解。但是抽象度越高,适应性就越强,代码相对就越简洁。

抽象粒度抽象程度高,也就间接导致抽象粒度细。抽象粒度细,控制性更好,但也导致了相对较难维护。

比如面向对象的23种设计模式,对于函数式编程来说,就是一句话的事。

以策略模式来说,Java的实现如下:

public class Context { private Strategy strategy; public Context(Strategy strategy){ this.strategy = strategy; } public void contextInterface(){ strategy.strategyInterface(); } }

public interface Strategy { public void strategyInterface(); }

public class ConcreteStrategyA implements Strategy { @Override public void strategyInterface() { //相关的业务 } } public class ConcreteStrategyB implements Strategy { @Override public void strategyInterface() { //相关的业务 } }

而对于Clojure来说,直接使用高阶函数就可以了:

(defn context [f] (f))(defn strategy1 [] (println "Strategy1")) (defn strategy2 [] (println "Strategy2")) (context strategy1)(context strategy2)

维护问题,可以把类看作一本书的章节,函数看作书的小节。一本书20个章节就算很多了,而小节至少有个大几十个,数量越多,越难维护。且因为抽象度高,函数如何放置的问题也需要花时间好好考虑。

评论列表暂无评论
发表评论
微信