他们说:“在类继承上,重要的对象组成”。
是。 这是蜘蛛侠。 您可能会在一篇关于编程,关于模式和其他与计算机科学相关的营销废话的文章中想知道他在这里做什么。
因此,他只希望您回忆一件事:
拥有权利的同时也被赋予了重大的责任
哪个权力?
让我们列举一下我们拥有的powers
:
- 功能
—班级
—变量
而已。 这些不是powers
,而是elements
。
您可以使用这些元素以不同的形式创建强大的咒语:
— FP
—玻璃钢
—面向对象
-命令式
- 还要别的吗
多数民众赞成在秘密-“从类继承的重要对象组成”并不意味着“类是sux,函数规则!”或“没有别的FP方式”。
这意味着“强大的力量将带来巨大的责任”,您必须谨慎处理一切。 否则,魔力会烧死你。
让我们从头开始。
在埃里克·埃利奥特 ( Eric Elliott)的“撰写软件”系列进行了中等讨论之后,我想写这篇文章。
首先让我重点介绍一些文章,我强烈建议您首先阅读:
它们都很有趣,但是我们将尝试从另一个角度进行挖掘。
让我们从头开始。
在计算机科学开始之初,在大多数计算机科学实际上是在计算机上完成之前,有两位伟大的计算机科学家:Alonzo Church和Alan Turing。 他们产生了两个不同但等效的通用计算模型。 两种模型都可以计算任何可以计算的内容(因此称为“通用”)。
阿隆佐·丘奇(Alonzo Church)发明了λ演算。 Lambda演算是基于函数应用程序的通用计算模型。 艾伦·图灵(Alan Turing)以图灵机闻名。 图灵机是一种通用的计算模型,它定义了一种理论上的设备,该设备可以操纵一条带子上的符号。
他们一起合作证明了lambda演算和图灵机在功能上是等效的 。
—函数式编程的兴衰
一步步。
现在您可能会在任何数字信号处理器中找到图灵机 ,甚至是命令式编程风格 。
图灵就是这样工作-逐步进行。
流。
Lambda演算以不同的方式工作。 程序是思想输入和输出的无尽flow
。 思想管道。
在某个点上的某个值是输入和输出的组合。 只要。 纯数学。 纯功能。
lambda创造了模拟设备的世界。
从现在开始,请把命令 式视为“ TODO list”,将功能式当作lambda“ vacuum lamp”。
并且不要忘记- 它们是平等的 。 您可能编写的所有FP代码将被编译为字节码,并在图灵机中执行。 但是该图灵机实际上将在CPU模块的模拟原子上运行。
这是无止境的。
函数式编程的兴起
我希望你知道,但是第一台计算机是模拟的。 最初的设备是模拟的。 并且几乎所有的现代军事或太空设备仍然是模拟的。
长话短说,但我父亲是一名程序员,实际上他已经向天空发射了火箭。
实际上,不像Google那样。
有一天我问他-“你在工作中做什么”。
他回答:“有人告诉我要用自我测试机制来建立模拟方案”。
我再次问:“模拟? 但为什么? 您应该使用常规的数字处理!”
并得到了一个答案:“ Cos 静态布线可以抵抗任何变化 。 没有什么可以改变“程序”工作的方式。 重新接线。 也不例外,也不辐射,也不美国人”。
让我改一下:
使用功能性方法,您将获得更多可测试,可维护和可预测的代码。
但是,只要长函数方法在功能上 等同于命令式—您可以在功能块内使用命令式样式。
仅仅因为这不是编程方法,而是架构。
如果您是通过隔离的模块构建应用程序的,这些模块通过functional pipes
相互连接,那么您将获得诸如微型方案之类的东西,如模拟设备。 每个元素都是一个黑匣子。 内部没有材料。
函数式编程的衰落
因此,在30年后,计算机发生了一些变化,并且数字时代开始了。 全新的CPU使每个人都可以使用高级语言,并且..
一个人使用这种强大的力量而没有重大责任。
新语言是新语言,它们是快速的,它们是为处理新的CPU而构建的,它们改变了世界。
但是它们的设计不能很好地处理Lisp可以处理的旧功能样式。
好的,您为什么要支持一些旧的摇摇欲坠的狗屎?
如果现在有人问我-您更喜欢Lisp,Closure还是Java-我将选择Java(好的,我将选择JavaScript)。
我们的父亲也这样做。 功能编程下降了。
今天。
然后有人发明了类和OOP。 1966年。30年后,OOP的“父亲”之一说:
实际上,我用“ 面向对象 ”这个词来形容 ,我可以告诉你我没有C ++ 。 —艾伦·凯。
因此,C ++,Java,JavaScript中的“类”和“ OOP”不是“类”或“ OOP”。 他们只有在阿兰斯的“意义”中才是“不”。
就像:你不是男人,你不是女人,你不知道乔恩·雪诺。
这只是一个名字。 它们可能因语言而异。
而且,如果艾伦不将现代班级视为阶级,那并不意味着现代班级很糟糕,甚至“不是真正的班级”。
这是一个开放的问题,为什么他要等待30年,为什么计算机科学不能以自己的方式发展,而必须保持一定的局限性。
今天不行。
但是,四人帮说今天不是“在类继承上比较喜欢对象的构成”。 他们在20年前做到了。
而且,如果您读了一本书,您可能会记得他们为什么这么说。
现在,请尝试理解以下内容:
发明并实现OOP和类的人非常聪明。 比你聪明。
他们实际上可以处理OOP的功能,并且没有任何问题。
不幸的是,您很笨,或者不如创始人聪明,或者只是不使用BDUF 。
甚至,即使您很聪明,也有很多时间去做BDUF等工作,但是您之后的某个人可能就不那么做了。
BDUF —预先进行大设计
正如互联网所说:
这是瀑布时代以前的遗物,每个人都变得凉爽敏捷。
这里的缩写是提醒我们不要被超复杂的体系结构所取代。 在编写第一行代码之前,我们不应该花3个月的时间设计应用程序。 从小处开始并进行迭代。
在精心设计的系统上,您不会有任何问题,而可以忽略任何文章和建议。 它们都是为其他人设计的,不是那么漂亮。
所有建议,书籍和模式,测试和最佳实践仅旨在解决一个问题:
帮助构建和维护设计不良的系统。 维护代码后,请帮助他人。 强迫某人摆在您面前,留下您将理解并接受的代码。
帮助团队合作。
而且,如果有任何摩擦,您将无法获得设计良好的系统。 而且,以我的经验-即使您将设计一个设计well designed system
-几年后您也可以意识到- 事实并非如此 。
PS:JFYI,大多数应用程序寿命不长。
答案。
但是我仍然没有提供关于为什么“对类继承的偏爱对象组成”被误解的信息。
让我再次发布Eric Elliott的短语
FP vs OOP是错误的二分法。
我可以说:
vs继承继承的对象组合就像是micro还是soft。
组合和继承之间没有相似之处。
他们俩可以以不同的方式做不同的事情。
它们都给你力量。 如何使用它取决于您。
您可以创建一个对象,该对象将构成其他对象的功能,然后使用继承来修改其行为。
或者,您可以创建静态布线方案,并使用继承来修改原子的行为。
我再举一次(最后一次!)埃里克
有人告诉我软件开发是“将复杂的问题分解为较小的问题,并组成简单的解决方案以形成对复杂问题的完整解决方案的行为。”
我一生中最大的遗憾之一是,我未能及早理解该课程的意义。
对象组合-是一种艺术品 。 将复杂问题分解为较小且可行的方法的贪婪方式。
类继承-是一种工具 。 积木。 一把锯。
而且,大多数类继承问题都源于未完成的分解。
试想一下-如果您不使用高级工具就能获得完美的结果,您将如何处理?
最后的陷阱
最后一个陷阱是最难的。
如果您“太多”使用继承-您将纠缠您的代码 。 到时候,很难“解开”。
如果您使用“太多”的分解方法,那么您也将纠缠您的代码。 很难找到以“单一责任原则”构建的小到小,小原子组件之间的思路的方式。
您必须考虑层,输入和输出,插槽和信号,块,并尝试使用独立的黑匣子构建整个应用程序。
分而治之 !
但
时刻牢记-
- 您并不孤单,有人(可能是您)必须支持您的代码,有人(可能是您)可能会更改您的代码。
- 旨在帮助您的编程语言。 和我。 还有鲍勃。 它们通常提供您应使用的更多功能。
- 如何编写可用和可测试的代码由您决定。 但是您可以将来自不同方法的不同技术结合起来。 您就可以做到。
- 没有人可以阻止你。
期待责任。
所有的魔术都是有代价的。
PS:CSS! 原子CSS! 功能性CSS! BEM! -这才是真正的战斗领域……。
From: https://hackernoon.com/favor-object-composition-over-class-inheritance-they-said-9f769659b6e