OOP是否实现了代码重用的承诺?有哪些替代方法可以实现代码重用?


56

使用面向对象范例的最大希望可能是代码重用。有人对此表示怀疑。为什么没有实现?

OOP定义的代码重用是否会使项目更高效?

或更易于管理?还是更容易维护?还是质量更高?

也许大家都同意代码重用是一件好事,但是有几种方法可以实现这一目标。问题是关于OOP提供的代码重用方法。这是好事吗?是否有比面向对象,子分类,多态等更好的方法来实现代码重用?有什么方法更好?为什么

告诉我们您在OOP重用或其他范式重用方面的经验。



7
它是互补的,不能完全重复。我改写为更好地理解差异。
Maniero

如果您可以投票认为这是一个有用的问题,或者在下面有有用的答案,请投票。StackExchange网站需要投票才能建立一个良好的社区。您每天可以投票30张,不要浪费它们。特别是享有较高声誉和低票数的用户,请阅读以下内容:meta.programmers.stackexchange.com/questions/393/…–
Maniero


2
@j_random_hacker:阅读评论。
Maniero

Answers:


34

代码重用是一个很好的主意。 不是一个伟大的

我有大约30年的软件工程经验,试图“重用”。

在发现我将70年代初构建的一个OS的设计重用到70年代后期构建的另一个OS后,我开始研究80年代的“代码重用”作为研究主题。

代码重用的好处是有时可以重用诚实的现有代码。但是世界充满了代码。如何找到想要的东西?这就是我所说的“ 重用诅咒”

我是圣诞老人(可以开源),我有10亿个软件组件。您可以有任何一个。

选择好运。

要很好地解决重用问题:

  • 重用者需要以某种方式指定他需要的内容(功能,性能,目标语言,环境假设等)
  • 必须有一个“可重用”代码库,并已通过这些潜在标准以各种方式建立了索引
  • 必须存在某种机制来挑选候选元素(十亿个元素,您不能亲自查看它们)
  • 必须有一种方法来表征所选择的候选者离规范有多远
  • 应该存在一些常规过程,以允许重用者修改所选的可重用代码(这是OOP的最大贡献:您可以通过覆盖现有组件/对象的插槽来对其进行编辑。OOP不提供任何其他帮助)。
  • 所有这一切显然必须比简单地重新编码便宜

多年来发现的大多数情况是,要使代码可重用,就必须为此目的而设计代码,或者其中包含太多隐式假设。实际上,最成功的代码重用库很小。可以说,库和框架是“可重用”的代码,它们非常成功。Java和C#成功的原因不是因为它们是非常好的计算机语言,而是因为它们具有大量精心设计,实施和记录的可用库。但是人们不会在库中查看源代码。他们只是调用了一个有据可查的API(设计为通常可用)。

没有进行代码重用(也不是OOP),这在我们对系统进行编码的能力方面提供了数量级的改进。

我认为关键的缺陷在于,任何类型的代码重用从根本上受到限制,因为代码内置了太多的假设。如果使代码很小,则可以最小化假设,但是从头开始构建的成本不是很高,并且重用收益无效。如果您使代码块很大,那么在新的上下文中它们几乎没有用。像格列佛(Gulliver)一样,它们被一百万条细细的绳子绑在沙滩上,而您根本承受不了割掉它们的全部费用。

我们应该做的是重用知识来构造代码。如果我们能够做到这一点,那么我们可以运用这些知识来构造我们所需的代码,并处理当前的假设集。

为此,仍然需要相同的规范功能来表征软件组件(您仍然必须说出想要的!)。但是,然后您将此“构造”知识应用于规范以生成所需的代码。

作为一个社区,我们对此还不是很擅长。但是人们总是这样做。我们为什么不能自动化呢?有大量的研究,这表明它可以在许多情况下完成。

为此所需的一个关键机械是用于接受“组件描述”的机械工具(这些只是正式文档,可以像编程语言一样进行解析)并将程序转换应用于它们。

编译器已经做到了这一点:-}而且,他们真的很擅长解决的问题。

具有代码生成功能的UML模型是一种尝试。这不是一个很好的尝试;在大多数UML模型中,人们所说的几乎是“我有看起来像这样的数据”。如果没有功能,很难生成一个真实的程序。

我正在尝试构建实用的程序转换系统,称为DMS的工具。通过将程序转换而不是抽象规范用于生成代码,而将遗留代码用于清理代码,可以使自己分心。(这些都是抽象中的相同问题!)。(构建这样的工具需要花费很多时间;我这样做已经有15年的时间了,与此同时,您必须吃饭)。

但是DMS具有我上面描述的两个关键属性:处理任意形式规范的能力以及捕获“代码生成知识”作为转换并按需应用的能力。值得注意的是,在某些特殊情况下,我们确实会根据规范生成一些相当有趣的代码。DMS很大程度上是使用自身来构建的,以生成其实现。这至少为我们实现了(知识)重用的一些希望:极大地提高了生产率。我有大约7名技术人员组成的团队;我们已经为DMS编写了1-2 MSLOC的“规范”,但是生成了10MSLOC的代码。

简介: 重用生成知识是胜利,而不是代码重用


4
恕我直言,最好的答案。重要的是知识/思想重用,而不是代码。
克拉韦米尔2015年

4
Mostly what has been discovered over the years is that for code to be reusable, it sort of has to be designed for that purpose, or it contains too many implicit assumptions.我也得出了类似的结论,但我不能这么简洁地表达出来。
biziclop

36

代码重用在OOP中实现,但在功能编程中也实现。每当您使用一段代码并使其余代码可调用它,以便您可以在其他地方使用此功能时,就是重复使用代码。

这种类型的代码重用还使代码更易于管理,因为更改此可调用块会更改其被调用的所有位置。我想说这个结果也提高了质量和可读性。

我不确定OOP是否只是用于提供代码重用。我将OOP视为与对象进行交互并抽象出数据结构的详细信息的一种方式。

从Wikpedia:

面向对象编程的起源可以追溯到1960年代。随着硬件和软件变得越来越复杂,可管理性常常成为人们关注的问题。研究人员研究了保持软件质量的方法,并开发了面向对象的编程,部分通过强烈地强调离散的,可重复使用的编程逻辑单元来解决常见问题。该技术着重于数据而不是过程,其程序由自足的模块(“类”)组成,每个模块的实例(“对象”)包含操纵其自己的数据结构(“成员”)所需的所有信息。这与多年来占据主导地位的现有模块化编程相反,后者专注于模块的功能,而不是专门针对数据,但同样提供代码重用,和自给自足的可重复使用的编程逻辑单元,从而可以通过使用链接的模块(子例程)进行协作。仍然存在的这种更常规的方法倾向于将数据和行为分开考虑。


9
+1功能编程可能是代码重用的方法。
乔纳斯(Jonas)2010年

1
@Matthieu M .:嗯,可重用性如何double sqrt (double x)?纯函数是可重用性的原型。
乔纳斯

3
@Joonas: ,,double sqrt(double x) 你可以定义他们中的很多,而与通用编程语言,你将不得不与它来完成。float sqrt(float x)int sqrt(int x)Number sqrt(Number x)
Matthieu M.

1
@Matthieu M .:的确,泛型减少了代码复制,因此它“更可重用”,是的。但是,我认为可重用性的真正关键是定义简单,小的,合理的纯函数(这是“函数式编程”的方向),并将其传递给C,这在C语言中是可能的。关于语言本身的功能。
乔纳斯

1
@Joonas:啊,我错过了字词,您是对的,编写小的纯函数真是太好了,甚至C都为此提供了指向函数的指针。
Matthieu M.

15

是和否

代码重用是许多不同活动的统称。

  1. 在单个项目中重复使用代码。OO非常适合此操作,一个经过精心设计的应用程序将紧密映射建模世界的关系,从而尽可能并建议消除重复的代码。但是,您可以辩称OO之前的技术可以实现相同的目标,这是事实,但是OO在许多方面更方便。
  2. 第三方库无论是否使用OO,这似乎都可以很好地工作。
  3. 跨用途代码重用 OO的最大代码重用承诺是,一旦为一个应用程序编写了代码,以后就可以将其重用于另一个应用程序,而这并不是专门为它设计的。当OO的概念在上层管理办公室的大门中过滤掉,而OO完全没有实现它时,这真是风靡一时。事实证明,目标是OO设计(以及可能是所有过程代码,但这只是我的理论)的关键方面,而重新使用代码的尝试以维护灾难告终。(没有人敢修改的旧框架的著名反模式,而它的朋友,每个应用的框架稍有不同,通常都源于此。)

13

我会回答很长,但是为什么呢?Udi Dahan解释得比我好得多。

http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/

这是帖子的开头:

这个行业早已重用。

有一种信念是,如果我们仅重用更多代码,一切都会更好。

甚至有人甚至说,面向对象的重点在于重用–事实并非如此,封装才是重中之重。在面向组件之后,应该重用的事情就发生了。显然,这并不是很顺利,因为在这里,我们现在将可重用的希望寄托在面向服务上。

完整的模式书籍已就如何实现面向一天的重用进行了编写。从实体服务和活动服务,到流程服务和编排服务,服务均通过各种方式对其进行分类。组合服务已被吹捧为重用和创建可重用服务的关键。

我不妨让您了解这个肮脏的小秘密:

重用是谬论


4
-1。大汉先生全神贯注于稻草人。没有人像他所暗示的那样认真地重用非通用代码,并且如果您从他的文章中删除该论点,那么他实际上是赞成或适当地重用了代码。
Steven A. Lowe 2010年

3
@Steven A. Lowe好,我希望那是真的。我希望您能走运,因为我已经看到了非通用形式的代码重用。不好看
托尼2010年

1
我确定不是-但是他们是认真的吗?dilbert.com/strips/comic/1996-01-31
Steven A. Lowe 2010年

1
商定,使代码可重用的成本确实很高,因此除非您在谈论Java或.NET基类的规模,否则它不会有回报。参见youtube.com/watch?v=aAb7hSCtvGw
Andomar,2011年

13

我同意克里斯的观点,函数式编程是重用代码的好方法。

许多程序具有重复出现的代码结构。为此,在OOP世界中使用了一些设计模式,但这可以通过递归函数和功能编程语言中的模式匹配来实现。有关这方面的更多信息,请参见《Real World Functional Programming》中的第一章。

我认为OOP中的深层继承在许多情况下可能会产生误导。您有一个类,并且许多密切相关的方法在不同的文件中实现。正如Joe Armstrong关于OOP所说的那样:

面向对象语言的问题在于,它们具有随身携带的所有隐式环境。您想要香蕉,但是得到的是一只大猩猩,拿着香蕉和整个丛林。

当涉及到代码重用时,高阶函数也非常有用,例如mapfoldr这是Google MapReduce的基础。

异步消息传递也是组织复杂软件的一种好方法,一些计算机科学家指出,就像“ 告诉,不要问 OOP”原理一样,假定对象之间可以异步通信。在“ 面向对象的编程:错误的路径?”中了解有关此内容的更多信息乔·阿姆斯特朗为引用:

我开始怀疑什么是面向对象的编程,我以为Erlang不是面向对象的,它是一种功能编程语言。然后,我的论文指导说:“但是你错了,Erlang是非常面向对象的”。他说面向对象的语言不是面向对象的。我可能会想,尽管我不太确定是否相信,但是Erlang可能是唯一的面向对象语言,因为面向对象编程的3个原则是,它基于消息传递,您在对象与对象之间具有隔离。有多态性

像事件驱动系统和Erlang中那样,异步消息传递也是使系统解耦的一种好方法,而松散耦合在复杂系统中也很重要。使用充分解耦的系统,您可以在系统运行时(可能在不同节点上)对系统进行升级。Unibet对此进行了精彩的演讲:域事件驱动架构

但是我认为大多数代码重用都是通过使用库和框架来完成的。


2
我喜欢大猩猩的那句话。^^
gablin 2011年

我以为问题是关于代码重用,而不是好的语义。
Daniel Lubarov 2011年

6

不起眼的unix管道在代码重用方面所做的功不可没。当对象出现时,对象只是碰巧的一种结构化代码的直观方式,后来人们开始将任何东西都放在上面。通常,对象是用于封装而不是用于代码重用,代码重用需要更多的东西,并且类继承层次结构不能很好地替代代码重用机制的真正含义。


4

OOP没什么特别的。您可以在有或没有OOP的情况下制作可重用的代码。纯函数特别可重用:例如,输入java.lang.math.sqrt(double)一个数字并给出一个数字。没有OOP,但是绝对比那里的大多数代码可重复使用。


4

从功能编程的角度来看,OOP主要是关于状态管理。

在函数式编程中,您可以轻松拥有数百个有用的列表函数:http : //haskell.org/ghc/docs/6.12.1/html/libraries/base-4.2.0.0/Data-List.html

List类中有数百种方法吗?公共方法被认为是您要保持内部状态的接口。

可悲的是,有些人没有(重新)使用许多小的功能,而是重复了功能。对我来说,这是因为OOP 不像功能编程那样鼓励代码重用


1
您的结论都是错误的,@ Lenny222。关于OOP,没有什么要求类维护状态。这是它的体系结构的一个问题,即它是在内部存储状态还是像Smalltalk的Integer类一样使用新状态实例化新对象。
2010年

1
很抱歉,我没有以防止这种误解的方式表达自己:我的意思是,OOP和FP之间的区别不是OOP可以比FP更有效地重复使用代码(标题暗示)。我在FP中经历了更好的代码重用。如果只有不可变的类,那么您在模拟FP,为什么首先要使用OOP?在我的POV中,它涉及命令式状态管理。
LennyProgrammers

3

对我来说,是的,但并非总是如此,它可以通过其他方式完成。

大多数时候,通过创建抽象基类并创建该类的具体实现。

还有许多框架利用继承来提供代码重用(Delphi,Java,.Net只是立即想到的一些)。

这并不是说许多实用程序库和代码片段也不能很好地完成这项工作,但是精心设计的对象层次结构让人有些满意。


3

根据我的经验,与使用继承层次结构等OOP原理相比,通过通用编程工具(如C ++模板)利用“可重用”代码取得了更大的成功。


2

OOP太开放,无法有效重用。

有太多的重用方法。每个公共班级都问:“给我一个新的实例!” ,每种公开方法都说:“给我打电话!” ,每种受保护的方法都会产生:“重写我!” -所有这些重用方式都是不同的,它们具有不同的参数,它们出现在不同的上下文中,都有各自的规则,如何调用/扩展/覆盖它。

API更好,它是OOP(或非oop)点的严格子集,但在现实生活中,API的功能过于强大且永远在增长,连接点仍然太多。同样,一个好的API可以使生活更轻松,这是为OOP提供接口的最佳方法。


Datadlow范例为组件提供了严格的接口,它们具有以下类型的端口:

  • 消费者(输入),和
  • 生产者(产出)。

根据域的不同,有一些数据包类型,因此消费者和生产者可以在它们具有相同(或兼容)端口的情况下进行连接。它最漂亮的部分是可以在视觉上完成的,因为没有参数或对连接的调整,它们实际上只是连接了消费者和生产者。

我有点不清楚,您可以看一下StackOverflow上的“ dataflow”标签,或Wikipedia的“ datafow编程”或Wikipedia的“基于流的编程”

(此外,我已经用C ++编写了一个数据流系统。因此,OOP和DF不是敌人,DF是更高级别的组织方式。)


2

在CommonLisp中,有很多方法可以实现重用:

  • 动态类型,默认情况下让您的代码通用

  • 命令式抽象,即子例程

  • 面向对象,具有多个继承多个分派

  • 语法抽象,定义新语法结构或缩写样板代码的能力

  • 功能抽象,闭包和高阶函数

如果您尝试比较CommonLisp体验到其他语言,你会发现,它可以简化代码重用的主要特点是存在两个面向对象和功能的抽象。它们比其他方法更具互补性:没有它们,您就不得不以笨拙的方式重新实现缺少的功能。例如,请参见用作闭包和模式匹配的函子类,以获取不可扩展的方法。


1

确实没有像人们描述它那样“重用”的东西。重用是任何事物的偶然属性。很难计划。大多数人在谈论“重用”时的意思是“使用”。这是一个远没有吸引力和令人兴奋的术语。使用库时,通常是按预期用途使用库。你是不是,除非你正在做一些与它真的疯了重新使用。

从这个意义上讲,在现实世界中的重用就是重新定义事物的用途。我可以在这里重复使用这些座椅,并重新排列它们以形成……床!不是很舒服的床,但是我可以做到。那不是他们的主要用途。我在其原始适用范围之外重用了它们。[...]明天,我将飞往英国。我不会重复使用飞机。我只会将其用于预期的目的,对此没有任何幻想或激动。

—凯夫琳·亨尼(Kevlin Henney)


3
人们会相信他们看到的任何印刷品。凯夫琳·亨尼(Kevlin Henney)是错误的,他的推理基于缺乏历史背景和较差的语义解释。从UNIVAC和IBM真空管计算机时代开始,重用代码是一项基本的编程原则。重用代码不是为了计划功能之外的其他功能而重新使用它。您编写并汇编了子例程(后来进行了编译),以生成目标代码,然后将其链接到程序中。重复使用确实的确意味着当今行业中通常所说的意思。
Huperniketes

如果编写两个功能完全相同的函数,则无论您使用它们多少次,都不会重用代码。
JeffO 2010年

椅子的比喻很好,除了一个词外,所有这些都只有一个:乐高。
biziclop 2011年

1

我将冒着嘲笑和自白的风险,我只是最近才使用OOP。它不会自动出现在我身上。我的大部分经验涉及关系数据库,因此我认为是在表和联接中。有人声称最好从一开始就学习它,这样可以避免在编程时必须重新思考。我没有那么奢侈,拒绝因为象牙塔理论而放弃我的职业。像其他所有事情一样,我会解决的。

起初,我认为整个概念没有任何意义。这似乎是不必要的,也太麻烦了。我知道,这是疯话。显然,您需要某种程度的理解,然后才能欣赏到任何东西的好处或为了更好的方法而忽略它。

代码重用需要不重复代码,了解如何完成代码以及预先计划。确定存在不值得的情况时,是否应该避免重用代码?而且没有一种语言严格地面向对象,以至于当您认为您应该从另一个类继承代码时,它将引发错误。充其量,它们提供了一个有利于实施的环境。

我认为OOP的最大好处是人们普遍接受代码的组织方式。其他一切都是肉汁。一组程序员可能并未就如何构造所有类完全达成共识,但他们应该能够找到代码。

我已经看到了足够的过程代码来知道它可以在任何地方,有时甚至在任何地方。


“而且没有一种语言是严格的面向对象的,以至于当它认为您应该从另一个类继承代码时,它将引发错误”-仍然没有!
史蒂文·劳

1

OOP为您提供了更多重用代码的方法。就这些。


OOP还促进接口重用和设计重用。
rwong 2010年

与其他范式(例如函数式编程(思维导图,组合器库等)和元编程)相比,它为我提供了更少的编写通用,可重用,高度抽象的代码的方式。实际上,当替代方法完全不受限制时,OOP似乎有一定程度的抽象杯。
SK-logic

@ SK-logic:正交。
Steven A. Lowe

1

横向复用:方面,特征,移植

经典OO有时无法实现代码重用,特别是当您疯狂地继承所有继承时,因为缺少在类之间共享实际功能的更好方法。对于此问题,已经创建了水平重用机制,例如AOP,特征和嫁接。

面向方面的编程

我认为AOP是OOP缺失的一半。AOP并不是真正众所周知的,但是它已用于生产代码。

我将尝试用简单的术语进行解释:假设您可以使用称为方面的特殊结构来注入和过滤功能,这些方面具有“方法”,这些方法定义了通过反射将影响什么以及如何受到影响,但是在编译时,这个过程称为编织

一个方面是一个例子,该方面告诉“对于以get开头的某些类的所有方法,您的程序将把获取的数据和获取的时间写入日志文件”。

如果您想更好地了解AOP,请观看以下两个讲座:

特性与嫁接

特性是用于定义补充OOP的可重用代码的另一种构造,它们类似于mixins,但更干净。

除了解释它们外,还有一个很棒的PHP RFC解释了两者。特质即将到PHP btw,它们已经提交到主干。

综上所述

在我看来,OOP仍然是模块化的关键,而今天我们众所周知,OOP仍然不完整


0

OOP提供了一组有用的工具,这些工具使您可以编写可以在没有这些工具的地方使用的代码。如果编写的PrintIt函数接受任何旧对象并对其进行调用.toString(),则在使用一种以上类型的对象调用该代码后,您将立即重新使用该代码。使用这些工具,每一行代码都能完成更多工作。

目前,功能编程非常受潮人欢迎。它为您提供了一整套单独的工具,以使每一行代码都能完成更多工作。它可能不是更好或不能用,但是在工具箱中提供了另一个工具。

(一个疯狂的想法是对整个面向对象的重用进行了额外的扩展:这个想法是我们可以定义一个Customer类,并在编写的每个应用程序中使用它。然后,应用程序到处都是胶水。这不能正常工作。但这并不意味着OO失败,甚至不意味着重用失败。应用程序内基本的代码重用类型使得编写性能更高的应用程序以及更快地编写它们成为可能。


0

阅读以上文章,有几点评论:

  • 许多人认为OOP中的代码重用意味着继承。我不同意。接口和协定是OOP系统中代码重用的核心。OOP是创建组件技术时的灰箱尝试。
  • 作为重用主题的领域特定和通用“框架”之间的区别,我认为太抽象了。以我的观点,只有很好地理解它所解决的问题,才能完成一个组件(简洁,最少和可重用的接口协定及其背后的实现)。特定于域的组件是(可重复使用的)组件,它使非领域专家可以在对领域知之甚少的情况下完成工作。用户需要了解界面,而不是问题域的复杂性。
  • 经常会忘记重用级别:构想重用,规范重用,体系结构/设计重用,接口重用,测试用例重用。重用代码并不总是有利的。但这通常可以节省大量时间,而坚持使用特定的体系结构来开发新的类似产品。
  • 在我看来,OOP设计模式(Gamma等人)详细阐述了战术实现技术,而不是在大规模重复使用代码的情况下有意义。它们帮助编写带有OOP元素的应用程序,但是我不会将它们视为解决单个应用程序之外的“代码重用”问题的解决方案。
  • 也许这是不公平的:20年的C / C ++ / C#经验和6个月的函数式编程(F#)。启用重用的主要要素是:人们需要轻松地找到“接口”,对其进行研究,理解然后再使用。纯粹的函数式编程使我不容易看到结构,重用的候选对象,或者从哪里开始以及从哪里结束。如此赞誉的“语法糖”通常是我眼中的盐,使我无法轻易看到发生的事情。因此,我不太可能尝试重用某个功能(它是什么-一堆功能?),它可能具有我什至看不到的隐藏副作用(懒惰的评估,monads等)。不要误会我的意思,函数式编程有很酷的一面,但是我看到的所有优点都带有很大的疑问。
  • 规范,设计,实现是耦合的,但对于“相同的事物”却不容易遍历。与提高编程效率,缩小差距,增加(自动推理,可追溯性)这些视图之间的共同利益相比,对于新的编程范例而言,提高未来的生产力至关重要。规范化的规范语言,标准化的测试符号(例如ttcn3)以及支持对接口和合同进行规范验证而又不加注释的编程语言可能是我们最迫切需要的。

0

问题是更微妙的恕我直言:

  1. OOP是一种构造具有可变状态的代码好方法。通过将状态封装到对象中,强制性的全状态代码变得更加易于理解,因为例如,如果某个状态被表示为类的私有字段,则您知道至少该特定状态只能通过此方法来修改类。(顺便说一句,您可以通过滥用继承轻松地打破这一优势。)这已经足够了,但是比没有这个要好得多
  2. 状态可变的代码本质上很难重用。比使用不可变数据结构的代码更难。

因此,从制作可重用代码的角度来看,OOP本身并不坏,但是使用OOP编写的代码种类本质上很难重用

同样,函数式编程可能会导致更多可重用的代码。但是在截止日期前正确地编写合理的功能代码以实现抽象可能是行不通的。而且,“半右”抽象将更易于表达OOP样式。而且,它往往不会使代码易于重用 -更高级别的抽象意味着对代码的理解将需要程序员有限的认知能力进行更高的前期投资。

举一个实际的例子:游戏代码涉及许多可变状态,因为这是考虑对游戏进行编码的自然方法,除非它是一种非常困惑/算法的游戏,所以显然最终要使用OO进行构造。当然,很难重用。但是,如果没有OOP,包含相同知识的相同代码将更难重用。并且将其重写为功能样式可能需要完全改变您对代码的了解方式以及其背后的知识。是的,在OO到FP重写之后,代码背后的知识会更加清晰……但是代价可能很大,而且可能是希望重用最终获得的非常聪明和抽象的代码的人也必须支付这种费用,因此,自相矛盾的是,即使从技术上讲它更可重用,人们最终也不会重用这些代码。

...这导致了最后一个微妙之处:代码重用与People | Code接口有关,而不仅仅是代码。OOP在提供此接口方面做得不错,因为它与当今人们思考的许多代码的映射很好。FP可能更适合代码重用,但是恕我直言,因为它不容易重用如今人们实际需要编写的那种代码。这将随着我们需要编写的代码类型而改变。

PS如果有人想说“ OO不是关于可变状态,那么您也可以使OO具有不可变状态” ...我称其为“使用类作为命名空间的FP”。当它为您工作时很好,它避免了某些语言的模块系统的某些缺点,并可能导致可重复使用的代码。但这不是OO;)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.