函数式范式与面向对象范式比较 — 以词频统计为例

Posted 区块链技术与应用研究实验室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数式范式与面向对象范式比较 — 以词频统计为例相关的知识,希望对你有一定的参考价值。

「函数式编程( Functional Programming)范式」与「面向对象( Object Oriented Programming )编程范式」的差异被经常提及。

今天写一篇文章,目的是通过一小段代码,直观地比较这两种范式的差异,希望能给感兴趣的同学们留下一个生动的印象。

注:本文中的 Java 代码来自于 Neal Ford 的 Functional Thinking

任务

输入一个句子,进行分词后先排除掉虚词,然后进行词频统计(不分大小写),最终得到一个单词为 Key,频率为 Value 的字典。

面向对象的 Java 源码


步骤归纳:

  • 构建虚词集合 NON_WORDS

  • 实现 wordFreq 函数

    • 生成空字典 wordMap

    • 遍历单词

      • 取词 + 小写化

        • 首次遇到则初始化

        • 重复遇到则 +1

函数式的 Elixir 源码

步骤归纳:

  • 构建虚词合集 @non_words

  • 构造 fetch_words_req 函数

    • words 进行分词

    • 分词后排除虚词

      • 通过 Enum 遍历,挨个排除

    • 统计词频

      • 遍历单词

        • 首次遇到则初始化

        • 重复遇到则 +1

范式对比

在面向对象范式下,我们看到一个叫做 Words 的机器人,拿起字符串切割成一个个单词,再对单词进行处理,最后得到一个结果。

在函数式范式下,我们看到一个叫做 Words 的车间里的一条叫做  fetch_words_req 的流水线,我们把字符串先通过 split 模块,再通过 reject_non_words 模块,最后通过 count 模块,得到我们想要的结果。

有了对比,我们就可以方便的理解以下问题:

  • 「面向对象范式」与「函数式范式」的差异究竟在哪里?

    A:使用「面向对象范式」,我们操纵机器人;使用「函数式范式」,我们操作流水线。

    很多教材、资料、文章等会说「OOP = 封装 + 继承 + 多态」。其实这个提法非常的误导人。封装是普遍存在的概念,函数也可以封装。而多态也不限于 OOP ,接口可以多态,用 duck typing 也可以多态。只有继承专属于 OOP ,但是继承只是 OOP 里一个次要一级的代码复用的特性(而且目前还普遍被认为不靠谱,composite over inheritance)。OOP最关键的特征还是通过消息传递来改变 Object 内部的状态。

    链接:https://www.zhihu.com/question/19732025/answer/530161703

  • 为什么在过去的开发中面向对象编程占主导?现在函数式火起来了?

    A:因为传统方式的确节约性能,在这个例子中只要对句子做一次遍历即可。但是代码的性能和清晰度是一个跷跷板,传统方式用性能换取了清晰度。现在硬件水平提升了,所以可以让代码清晰度占更重的分量,所以——更具有清晰度的函数式编程火起来了。

  • 什么时候选择面向对象?什么时候选择函数式?

    A:一个业务领域建模,其实模拟的就是现实当中的不同角色的人/机构的工作方式。因为如果是人/机构互相协作,就是通过消息来协作的。比如博士生想发文章,先得自己写,写了老板审阅,完事发给期刊编辑,编辑找同行评议,完事发表,发表的结果会收录到某个文献索引数据库。这个过程就是多个独立的“对象”在相互协作的结果。因此OOP在这个层面上对这个流程进行抽象是很合适的。当然你也可以说,这时我用FP的各种动作函数的组织来描述这个过程,也是可以的。但是如果比较一下,这个场景用FP和OOP建模,哪个更容易理解呢?

    再比如,对一组数据做加工,先查询,然后聚合,聚合后排序,再join,再排序,再聚合,再转换(map)得到最终的结果。这个过程,用FP的函数就很自然。

    链接:https://www.zhihu.com/question/19732025/answer/530161703

  • 「函数式、面向对象、命令式、声明式」这四者究竟是什么关系?

    命令式编程(Imperative):详细的命令机器怎么(How)去处理一件事情以达到你想要的结果(What);

    声明式编程( Declarative):只告诉你想要的结果(What),机器自己摸索过程(How)。

    链接:https://zhuanlan.zhihu.com/p/34445114

    我个人认为,「命令式」和「面向对象」是一枚硬币的两面;「声明式」和「函数式」是另一枚硬币的两面,欢迎探讨。





后台输入关键字有自动回复:

输入「 刷题 」,推送LeetCode刷题系列;

输入比特币 」,推送比特币技术入门教程;

输入「 联盟链 」,推送联盟链开发系列教程;

输入「 项目 」,看看大狗最近在玩什么;

输入大狗 」,推送我的个人微信二维码。

以上是关于函数式范式与面向对象范式比较 — 以词频统计为例的主要内容,如果未能解决你的问题,请参考以下文章

面向对象编程

面向对象编程

编程范式:范型编程函数式编程面向对象

无状态面向对象编程与函数式编程?

javascript 函数式编程

Java面向对象编程导论