面向对象编程的绝地反击 已翻译 100%

oschina 投递于 2017/08/07 11:39 (共 11 段, 翻译完成于 08-14)
阅读 4376
收藏 7
3
加载中

免责声明:该帖子含有幽默成分,如果您对幽默类题材比较敏感,建议您停止阅读。

最近,我阅读了发布在 DZone 上的关于面向对象编程的文章。我在博客上发现过好几篇关于面向对象编程的函数编程文章。所有这些帖子都在说,面向对象编程已经死亡(或多或少)。我认为所有这些帖子存在基本问题的误解:没有真正理解什么是函数编程。现在是时候让我谈谈不同编程范式之间的争论了。

首先,我想说,我尊重上述文章作者的意见。我要说的是我个人对这个问题的看法。对这个富有争议的问题上没有绝对正确或绝对错误的观点。所以,请大家不要互相攻击。

亚林瓜子
亚林瓜子
翻译于 2017/08/07 11:48
1

函数式编程是什么?

我认为为了更好地理解我对函数式编程的观点,首先必须理解函数式编程是什么意思。

在计算机领域,函数式编程是一种编程范式 [..] ,它将计算机运算视为数学上的函数计算,并且避免状态变更以及数据可变。

这是维基百科给出的定义。你读过 lambda 表达式吗?没有。因此,在代码中滥用 lambda 表达式并不意味着您使用的是函数式编程范型。

根号7
根号7
翻译于 2017/08/07 16:16
1

首先,您需要“引用透明性”,这意味着任何时候使用相同输入的调用函数必须返回相同的输出。实现引用透明性的先决条件是状态的不变性。一旦创建了一个结构(我们可以说一个类型?),就不能在随后以任何方式进行修改。

简单吗?引用透明性意味着没有副作用,没有异常抛出,没有从外部来源的读取等等。如果没有这些能力,我们如何才能实现高产出呢?

Tocy
Tocy
翻译于 2017/08/07 13:26
0

故事的难点

我们似乎被困在一个黑洞里,不是吗?我不能在一个函数内产生副作用(这并不坏),我不能向函数调用者发出信号,说可能出了问题,我不能访问任何外部资源。哦,天哪!

你听说过幺半群、函子、单子吗?这些结构直接来自于范畴论,数学的一个分支。描述这些结构超出了本文的范围,但我们可以举一些例子。

圣洁之子
圣洁之子
翻译于 2017/08/07 16:34
1

我确定地知道你在你的代码中至少使用一些单子(Monad)。如果你是一个 Scala 开发者,很可能你使用过 Option[T] 类型,或 [T, E],或任何一种集合比如 List[T]、Set[T] 等。如果你是一个 Java 开发者,你可以把 Optional<T>、Collection<T> 和 Stream<T> 类型纳入考虑。所有这些类型都是单子(Monad)。

这些类型从行为的角度看没有任何共同之处,这意味着单子(Monad)是一种机制,用于在彼此不直接相关的类型之间共享一些属性(基本上,代码复用)。这是什么意思?下文引用自 Scala 设计模式

单子(Monad)结构代表计算的步骤序列。单子(Monad)被用于构建一切都不可变的管道,而干净利落地给一门语言增添带有副作用的操作。

圣洁之子
圣洁之子
翻译于 2017/08/07 16:57
0

让我们从优秀图书 Scala 函数式编程借用单子(Monad)的定义:

一个单子(Monad)是一元组合子的最小集(即 unit 和 flatMap)之一的实现,满足结合性和同一性的法则。

一元结合子?结合性?同一性?独角兽?Wtf?!!? 我只是一个普通的开发人员:我听说过数学,我改变编程范式。

我想用这篇论文来说明什么?真正的函数式编程实际上涉及数学规律和理论。如果你遵从这些规律开发你的程序,就会从一组好的属性中获益,比如可组合性、可测性、线程限制,直接来自数学理论。

然而,你需要学习数学。范畴论的小雨滴将会沾湿你的脸庞。

圣洁之子
圣洁之子
翻译于 2017/08/07 17:23
0

面向对象编程

面向对象编程是什么呢? 你有没有遇到过你必须遵循的无聊的数学法则? 你有没有听过有关诸如 monad 或 functor 这样的深奥词汇,还是别的什么? 你有没有将一些数学理论应用于面向对象的程序中?

没有。面向对象编程的美丽之处在于它是与数学无关的。每个人都可以学习面向对象的编程语言,如 Java、C ++ 或 Kotlin。第一印象里,面向对象的编程非常接近于我们看待现实世界的方法。

Tocy
Tocy
翻译于 2017/08/07 17:28
0

作为生活在世界幸运地区的人类,我们知道车都是由发动机、一些轮子、一个车身等构成的。我们明白 Car 类型是什么意思,为什么它拥有引擎、车轮和车身的属性。

面向对象编程比函数式编程更容易学习。 到此为止。这是唯一的事实。 从计算机时代开始,这两种模式就或多或少地存在(例如,想想在 1958 年发明的 Lisp)。你有没有听说过用函数式编程语言来编写的操作系统的? 没有。

Tocy
Tocy
翻译于 2017/08/07 13:34
0

简单化导致的权衡

更简单意味着更少的约束。  更少的约束意味着更少的拘泥于形式。更少的形式意味着更容易用一种错误的方式使用编程语言的特性。

以我们刚刚提出的一元定义为例。 在定义中,类型必须满足的约束是非常明确的指定为一元。 数学不会说谎。

现在,采用面向对象编程的任何原则:例如,单一责任原则。 原则规定:

一个类只因一个理由而改变。

孤独的阅读者
孤独的阅读者
翻译于 2017/08/07 18:30
1

需要改变的原因究竟是什么?所有适用于函数编程语言的数学魔法在哪里?没有。

在与面向对象编程有关的所有理论的基础上,耦合的定义都不是以正式的方式定义的。

组件之间的耦合取决于其依赖程度。

好吧,那么如何衡量组件之间的依赖程度? 没有正式的方式。 我试图在我过去的帖子“依赖关系”中给出耦合的数学定义,但这只是一个试验。

缺乏严谨的原理定义导致了原理的解读。个人的解读往往导致错误和不良做法。

总长
总长
翻译于 2017/08/14 09:50
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(14)

MZHS
MZHS

引用来自“梅开源”的评论

面向对象本来是好的,但是一大堆get set以及为了解决继承和接口和强类型而引入各种奇技淫巧后, 看这些代码已经不再享受智慧的共鸣。

引用来自“MZHS”的评论

get set在解决多线程修改变量查错方面很有用

引用来自“LinkerLin”的评论

不要共享变量,通过消息来传递。

引用来自“MZHS”的评论

公司里你控制不了别人怎么写代码,我的意思就是在debug和生产环境抓log时,有get和set一抓一个准。如果你碰到的变量值和你推理出来的值不一样的时候,就需要在set处抓内奸,看看是谁改了值,如果想看都是谁用了该变量的值的时候,get就起到了作用。一个管修改,一个管权限,就跟出入境管理是一样一样的

引用来自“水山清风”的评论

弱弱的问一句,在 scala 里面,val 变量的值是无法改变的,那你还 debug 什么。。。
不了解scala,java里被final修饰的基本数据类型变量也是不能被修改的。既然都是一个常量了,一般除了出了不是被三方程序修改(像八门神器这种),就是传错了变量,也是需要debug的。
水山清风
水山清风

引用来自“梅开源”的评论

面向对象本来是好的,但是一大堆get set以及为了解决继承和接口和强类型而引入各种奇技淫巧后, 看这些代码已经不再享受智慧的共鸣。

引用来自“MZHS”的评论

get set在解决多线程修改变量查错方面很有用

引用来自“LinkerLin”的评论

不要共享变量,通过消息来传递。

引用来自“MZHS”的评论

公司里你控制不了别人怎么写代码,我的意思就是在debug和生产环境抓log时,有get和set一抓一个准。如果你碰到的变量值和你推理出来的值不一样的时候,就需要在set处抓内奸,看看是谁改了值,如果想看都是谁用了该变量的值的时候,get就起到了作用。一个管修改,一个管权限,就跟出入境管理是一样一样的
弱弱的问一句,在 scala 里面,val 变量的值是无法改变的,那你还 debug 什么。。。
h00kran
h00kran
面向对象是好的,但是一个问题直接的解决方法有那么多种,而且效率不相上下,未免让我心烦。
沙枣
沙枣
我是做移植的,纯面相对象的代码迁移到函数式语言的环境中,比重构都难。相反的话,就容易很多。
orpherus
orpherus

引用来自“梅开源”的评论

面向对象本来是好的,但是一大堆get set以及为了解决继承和接口和强类型而引入各种奇技淫巧后, 看这些代码已经不再享受智慧的共鸣。
那是语言的锅,不是面向对象的锅。现代语言可不用写一堆getter/setter。
Raynor1
Raynor1
好吧。。两种都可以直接用啊。。又不冲突的咯。。真是二。。
秋风暮霞惋红曲
秋风暮霞惋红曲
绝地反击....无语
MZHS
MZHS

引用来自“梅开源”的评论

面向对象本来是好的,但是一大堆get set以及为了解决继承和接口和强类型而引入各种奇技淫巧后, 看这些代码已经不再享受智慧的共鸣。

引用来自“MZHS”的评论

get set在解决多线程修改变量查错方面很有用

引用来自“LinkerLin”的评论

不要共享变量,通过消息来传递。
公司里你控制不了别人怎么写代码,我的意思就是在debug和生产环境抓log时,有get和set一抓一个准。如果你碰到的变量值和你推理出来的值不一样的时候,就需要在set处抓内奸,看看是谁改了值,如果想看都是谁用了该变量的值的时候,get就起到了作用。一个管修改,一个管权限,就跟出入境管理是一样一样的
全体人员
全体人员

引用来自“黑传说”的评论

一层层不断套,套着套着就出问题了。另外,函数式编程和对象编程有啥关系????
就像PHP和Java的关系:laughing:
黑传说
黑传说
一层层不断套,套着套着就出问题了。另外,函数式编程和对象编程有啥关系????
返回顶部
顶部