告别相杀!面向对象和函数式编程共存
作为结构化编程的一种,函数式编程正受到越来越多的重视。而作为常用的一种程序开发方法,面向对象编程为程序设计带来了更强的灵活性和可维护性。那么两者相较而言,究竟有着什么样的区别?应用场景又有何不同?
作者 | Reginald Braithwaite
译者 | 彼得
责编 | 屠敏
出品 | CSDN(ID:CSDNnews)
简单来说,函数式编程(“FP”)和面向对象编程(“OOP”)具有相似的表达能力和封装能力,它们都可以将程序封装成可以自由组合的较小部分。
但是这两个“思想流派”之间的还是存在着很多区别。其中最大的差别在于对数据和数据操作之间关系的不同处理。
FP 和 OOP 的区别
面向对象编程的核心思想是将数据和对数据的操作进行紧密耦合:一个对象除了拥有自己的数据,还拥有对数据操作的实现。这些对象对外隐藏这些具体的信息。它们通过接口,进行响应的方法或消息来和其它对象交互。 因此,在面向对象编程中,抽象的核心是数据,这些数据通过接口等API对外展示。
在面向对象编程中,人们所作的主要工作就是创建新对象或者通过增加新方法来扩展现有对象。
函数式编程的核心原则是数据只与功能进行松散的耦合。你可以对同一个数据结构定义不同的操作。在这里,抽象的核心是函数,而不是数据结构。函数隐藏了它们的具体实现、编程语言的抽象以及函数之间进行组合或表达的方式,例如泛型函数或组合函数。
在函数式编程里,人们的主要工作就是编写新函数。
在自然界中,如果熊和鳄鱼之间爆发冲突,地形会决定双方争斗的结果。
对于函数式编程和面向对象编程来讲,它们在什么情况下,其中的一个比另一个更合适呢? 因为这是一个实用的博客,所以,我将忽略所有理论上的考虑因素,例如机械地推理代码的能力和实施项目时的限制条件,比如资源不足,时间不足等。
在实际的环境中,你认为这两者中的任何一个会是压倒性的“赢家”吗?这个可能得花些时间好好想想。在你思考的时候,我会先享受一杯浓咖啡...
何时使用 FP?何时使用 OOP?
当然,答案是,业务编程主要是由功能模型,而不是面向对象模型进行控制的。 这是一个让你觉得惊讶的答案吗?如果你的头脑里只考虑Java,C ++,C#和Ruby,也许这个答案会令你觉得奇怪。
你知道,所有的面向对象通常都是对访问各种支持 SQL 的数据库的模拟。 SQL是一种非常实用的数据库操作的脚本语言。你可以对数据库进行设定,使得对它所有表格的访问都是通过PL/SQL的存储过程完成的,但是因为这样会产生严重的编程问题,所以,实际中很少这样做。
关系型数据库的主要好处是它可以满足未来的需求。如果你需要新的报告,那随时可以创建它们。许多不同的应用程序可以与同一个数据库进行通信。这些程序之间的数据一致性可以通过数据库的约束条件来强制实现。
如果你仔细研究一下,就会发现数据库本身其实就是一个大的数据结构,而应用程序则是对数据库中的数据进行的操作。几乎每个商务应用的核心都是一个大的功能性的数据库,也就是一个数据结构和一系列对数据进行的操作。
OOP 使用场景
但是,我们在应用程序中包含对象只是为了符合潮流吗? 或者说,我们在编写应用程序时做的事情和创建数据库时做的事情有什么本质上的不同吗?
这个问题答案就在于面向对象和使用数据库各自有什么好处。
一个精心设计的面向对象的架构可以轻松改变对象的组合方式。 隐藏实现和解耦使您可以轻松地更改对象之间的关系。使用面向对象本身,并不会使添加新的操作变得更容易。如果在代码中发现双重调度和访问的问题,你就能够真正地感受到这一点。
但是,假如有一个订单处理系统,如果你的业务规则发生了变化,需要相应地修改订单的处理流程,你就会发现面向对象的优势。 那些不受这些变化影响的对象和受影响的对象是互相隔离的。
另一方面,精心设计的数据库会使添加新查询和操作变得很容易。如果你需要以新的方式查看现有的数据或者如果您需要向数据添加新的更新类型,它都能够很好地处理。 客户端应用程序在逻辑上与提高性能的索引等问题互相隔离。
这样做并不会使改变关系变得更容易。如果更改管理结构,使报表和管理器的关系从一对一变为多对多的矩阵管理结构,那么这种更改将破坏许多应用程序。
因此,如果我们记录了所有在商业软件中需要实现的内容,我们需要把那些代表长期的、相对不变的关系的东西放在数据库中保存,把那些代表短期操作、随着时间的推移而发展和变化的内容,在应用程序中实现。
应用程序的堆栈通常比数据库的堆栈高四倍,这很正常。事情确实发生了变化,企业也应该不断地学习、成长和发展。
FP 的应用场景
那么,我们通常所说的函数式编程,也就是用多范式语言中的函数式编写的代码怎么做?我们可以简单地将面向对象程序改写为作用于相对静态的数据结构上的操作集合吗?
通常来说,这样都是可以的。但同时必须优先考虑这种关系的相对寿命。那些本身不太可能改变,但是被经常改变的实体所操作的内容应该以一种函数式编程来实现,而那些相对经常改变的东西可以用面向对象的风格来实现。
如果每个管理器都有一个或多个报表,并且每个报表都只有一个管理器,那么将这种关系通过API进行隐藏就几乎没有什么好处了,因为在API中,管理器对象以隐含的方式来委托操作。对于这种关系,最好的处理方式是先构造数据,然后对数据进行操作。
但是关于运输成本的规则很可能会改变,所以,最好你把它封装起来,以便程序的其它部分不被将来可能的变化所影响。
因为好的软件需要满足不止一种需求,所以,它们一般都包含这两种风格。
原文: http://raganwald.com/2013/04/08/functional-vs-OOP.html
作者简介: Reginald Braithwaite,他的兴趣包括构造超现实数字,析构空值,以及庆祝编程的乐趣。他是JavaScript Allongé、CoffeeScript Ristretto和raganwald.com的作者。他在pagerduty开发用户体验.
本文为 CSDN 翻译,如需转载,请注明来源出处。
热 文 推 荐
华为立 Flag:一年超越三星做全球智能手机老大!
中高级前端面试秘籍!金三银四如何直通大厂?!(长文)
VS Code Java 开发指南!
☞ 那些简历造假拿 Offer 的程序员,后来都怎么样了?
☞ 被V神点赞, 我是如何用五子棋打败以太坊排名最高的应用的? |人物志
☞ 50个最有价值的数据可视化图表(推荐收藏)
一键免费自动AI抠图,效果连PS大哥也点赞!
史上最难的一道Java面试题
print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!\n");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"
点击“阅读原文”,打开 CSDN App 阅读更贴心!
喜欢就点击“好看”吧!
告别相杀!面向对象和函数式编程共存相关推荐
- 《Java8实战》笔记(15):面向对象和函数式编程的混合-Java 8和Scala的比较
面向对象和函数式编程的混合:Java 8和Scala的比较 Scala是一种混合了面向对象和函数式编程的语言.它常常被看作Java的一种替代语言,程序员们希望在运行于JVM上的静态类型语言中使用函数式 ...
- Reactor事件驱动的两种设计实现:面向对象 VS 函数式编程
内容目录: Reactor实现架构对比 面向对象的Reactor方案设计 函数式编程的Reactor设计 示例对比 两者的时序图对比 结论 Reactor事件驱动的两种设计实现:面向对象 VS 函数式 ...
- 【2023】Kotlin教程 第二篇 面向对象与函数式编程 第15章 数据容器——数组和集合 15.2 集合概述
[2023]Kotlin教程 文章目录 [2023]Kotlin教程 第二篇 面向对象与函数式编程 第15章 数据容器--数组和集合 15.2 集合概述 第二篇 面向对象与函数式编程 第15章 数据容 ...
- 图灵奖得主Alan Kay谈面向对象和函数式编程
Alan Kay授权<程序员>整理翻译并本文.译/王江平 原文链接 https://news.ycombinator.com/item?id=11808551 本文为<程序员> ...
- Java 设计模式最佳实践:一、从面向对象到函数式编程
原文:Design Patterns and Best Practices in Java 协议:CC BY-NC-SA 4.0 贡献者:飞龙 本文来自[ApacheCN Java 译文集],采用译后 ...
- 测试和恢复性的争论:面向对象vs.函数式编程
Michael Feathers最近的博文在博客社区引发了一场异常激烈的论战.Feathers发表言论说一些面向对象编程语言的内嵌特性有助于测试的进行,并且使用面向对象编程语言编写的代码更容易恢复. ...
- javascript中的面向对象_面向对象和函数式编程的本质区别
编程的本质 当写过许许多多程序后,接触了那么多编程模式.设计模式.框架.语言.算法.数据结构以后,就会发现编程的本质万变不离其宗就是,操纵一坨数据.当然操纵的方式有许多,存储的方式也五花八门,但是本质 ...
- javascript消除字符串两边空格的两种方式,面向对象和函数式编程。python oop在调用时候的优点...
主要是javascript中消除字符串空格,比较两种方式的不同 //面向对象,消除字符串两边空格 String.prototype.trim = function() { return this.re ...
- C#中面向对象编程中的函数式编程
目录 介绍 面向对象编程中仿真的函数式编程技术 粒度不匹配 面向对象的函数式编程构造 相互关系函数式编程/面向对象程序设计 C#中的函数式编程集成 函数级别的代码抽象 操作组合 函数部分应用和局部套用 ...
最新文章
- WinForm 应用程序中开启新的进程及控制
- Luence简单实现1
- 并查集+二分-hdu-4750-Count The Pairs
- h264 I帧的判断
- oracle rac redo log,RAC共享online redo log和archived log的官方说明
- centos 7 elk安装与搭建
- HDU 1864 最大报销额(01背包)
- DiskFileUpload类
- keil4 c51安装教程
- 无pygame写一个python贪吃蛇
- Jack Lin tools 3Dmax批渲染插件
- QMC解码-某音乐解码
- 三维扫描3D打印在创客教育中的实际应用
- freemarker word模板导出图片循环
- 采样频率-控制频率-开关频率
- 论文翻译—Ciphertext-Policy Attribute-Based Encryption
- OpenCV学习笔记03:缩放裁剪图像与调整图像色调
- Oracle rtrim、to_char函数格式化数字 小数Format展示,FM999990D99
- 播音计算机论文,播音主持论文的题目或论文内容
- 讲讲如何写论文和发论文(通信类)
热门文章
- python内置函数可以返回列表元组_十九、python内置函数汇总
- linux系统切换清华源(自带的源下载速度太拉跨)
- vscode+leetcode环境配置
- html属性是dom属性吗,HTML DOM 属性 对象
- 原生开发什么意思_什么是原生开发?什么是混合开发?两者有什么区别?
- 【图像处理】图像灰度级减少, 图像缩放(Reducing the Number of Gray Levels, Zooming and Shrinking)
- Unity5 Survival Shooter开发笔记(1)
- 水起泡器行业调研报告 - 市场现状分析与发展前景预测
- C语言作业 – 数组排序算法可视化
- 苹果iPhone系列成交额5秒破亿;荣耀回应:没有安卓授权是假消息;魅族宣布将接入鸿蒙系统|极客头条...