程序编程是否比OOP有任何优势?

时间:2009-02-09 14:02:07

标签: oop object scope procedural-programming

[编辑:]之前我问过这个问题可能是一个关于何时使用OOP与何时使用程序编程的错误框架问题 - 一些回复暗示我要求帮助理解OOP。相反,我经常使用OOP但想知道何时使用程序方法。从回答来看,我认为有一个相当强烈的共识,即OOP通常是一种更好的全方位方法,但如果OOP架构不能长期提供任何重用利益,则应该使用过程语言。

然而,我作为Java程序员的经历却不然。我看到了一个庞大的Java程序,我用Perl大师重写了我编写的代码的1/10,看起来和我的OOP完美模型一样强大。我的架构看到了大量的重用,但更简洁的程序方法产生了一个更好的解决方案。

所以,冒着重复自己的风险,我想知道在什么情况下我应该选择一个过程而不是面向对象的方法。您如何预先确定OOP架构可能过度杀伤并且程序方法更简洁高效的情况。

有人可以建议这些情景的样子吗?

通过程序编程方法提前确定项目的好方法是什么?

23 个答案:

答案 0 :(得分:43)

在重复使用时,我喜欢Glass' 3条规则(这似乎是您感兴趣的内容)。

  

1)难度是3倍   将可重用组件构建为单个组件   使用组件
2)可重复使用   组件应该尝试三个   它之前的不同应用程序   足够普遍接受   重用库

由此我认为你可以推断出这些推论

  

a)如果您没有预算   花费3倍于你的时间   也许是为了构建一个单一的使用组件   你应该推迟重用。 (假设难度=时间)
  b)如果   你没有3个地方   使用你正在构建的组件,   也许你应该推迟建设   可重用的组件。

我仍然认为OOP对于构建单一用途组件很有用,因为你总是可以将它重构为以后真正可重用的东西。 (您也可以从PP重构为OOP,但我认为OOP在组织和封装方面具有足够的优势,可以从那里开始)

答案 1 :(得分:15)

可重用性(或缺乏可用性)不受任何特定编程范例的约束。根据需要使用面向对象,程序,功能或任何其他编程。组织和可重用性来自您的工作,而不是工具。

答案 2 :(得分:14)

你自己给出了答案 - 大项目只需要OOP来防止过于混乱。

从我的角度来看,OOP的最大优势是代码组织。这包括DRY和封装的原则。

答案 3 :(得分:12)

我建议使用最简洁,基于标准的方法,您可以找到任何给定的问题。使用Perl的同事证明,无论采用何种方法,熟悉特定工具的优秀开发人员都可以取得很好的成果。与其将Java-versus-Perl项目作为程序与OOP争论的一个很好的例子进行比较,我希望看到Perl和类似简洁的语言(如Ruby)之间的对峙,这恰好也有好处面向对象。现在,这是我想看到的东西。我的猜测是Ruby会出现在顶部,但我不想在这里引发一场语言火焰战 - 我的观点只是你选择了适合这项工作的工具 - 无论何种方法都能以最有效和最强大的方式完成任务。方式可能。 Java可能很强大,因为它的面向对象,但是当你和你的同事以及许多其他转换为动态语言(如Ruby和Python)的人现在都在寻找时,那里有更高效的解决方案,无论是程序还是OOP。

答案 4 :(得分:10)

那些虔诚支持OOP的人没有任何事实证明他们的支持,正如我们在这些评论中所看到的那样。他们在大学接受培训(或洗脑),只使用和赞美OOP和OOP,这就是为什么他们如此盲目地支持它。他们在PP中做过任何真正的工作吗?除了在团队环境中保护代码免受粗心程序员的影响,OOP并没有提供太多帮助。在PP和OOP中亲自工作多年,我发现PP简单,直接且效率更高,我同意以下明智的男女:

(参考:http://en.wikipedia.org/wiki/Object-oriented_programming):

许多着名的研究人员和程序员批评了OOP。这是一个不完整的清单:

  • Luca Cardelli写了一篇题为“Bad Engineering Properties of Object-Oriented Languages”的论文。

  • Richard Stallman在1995年写道,“向Emacs添加OOP并不是一个明显的改进;我在使用Lisp Machine窗口系统时使用了OOP,我不同意通常认为它是一种优秀的编程方式。“

  • Potok等人的一项研究。 OOP和程序方法之间的生产率没有显着差异。

  • Christopher J. Date指出,由于缺乏对OOP的一致同意和严格的定义,OOP与其他技术的关键比较(特别是关系)很难。提出了OOP的理论基础,它使用OOP作为一种可定制的类型系统来支持RDBMS。

  • 亚历山大·斯捷潘诺夫(Alexander Stepanov)认为,OOP提供了一种数学上有限的观点,并将其称为“几乎与人工智能一样的骗局”(可能指的是20世纪80年代的人工智能项目和营销,有时被视为过度热心)回想起来。)

  • Paul Graham建议OOP的目的是充当“羊群机制”,让普通组织中的平庸程序员不要“做太多伤害”。这是以减慢知道如何使用更强大和更紧凑的技术的高效程序员为代价的。

  • Erlang的主要发明人Joe Armstrong被引用说:“面向对象语言的问题在于他们已经拥有了所有这些隐含的环境。你想要一个香蕉,但你得到的是拿着香蕉和整个丛林的大猩猩。“

  • Richard Mansfield,作者和COMPUTE的前编辑! “杂志”指出,“像多年来无数其他知识分子一样(”相关性“,共产主义,”现代主义“等等 - 历史上都充满了它们),OOP将与我们同在,直到最终现实宣称自己为止。但考虑到OOP目前遍及大学和工作场所,OOP可能被证明是一种持久的妄想。整整一代经过深思熟虑的程序员继续走出学院,一直致力于OOP,而且他们的余生都只是OOP。“并且还引用了一句话说”OOP是编写一个程序,机场安检的目的是飞行”

答案 5 :(得分:6)

我认为DRY原则(不要重复自己)与一点敏捷相结合是一种很好的方法。从最简单的工作开始逐步构建程序,然后逐个添加功能,并在必要时重新考虑代码。

如果您发现自己一次又一次地编写相同的几行代码 - 可能使用不同的数据 - 是时候考虑抽象可以帮助将那些变化的东西与保持不变的东西分开。

为每次迭代创建彻底的单元测试,以便您可以放心地重新计算。

花费太多时间试图预测代码的哪些部分需要可重用是错误的。一旦系统开始增长,它很快就会变得明显。

对于拥有多个并发开发团队的大型项目,您需要有一些架构计划来指导开发,但如果您自己或在小型合作团队中工作,那么如果您坚持DRY,架构将自然而然地出现原理

这种方法的另一个优点是,无论你做什么都是基于现实世界的经验。我最喜欢的比喻 - 在你能想象建筑物是如何建造之前,你必须先玩砖块。

答案 6 :(得分:4)

我认为当你有一个非常明确的问题时,你应该使用程序风格,规范不会改变,你想要非常快运行程序。在这种情况下,您可以交换性能的可维护性。

通常情况下,当您编写游戏引擎科学模拟程序时就是这种情况。如果你的程序每秒计算的次数超过百万次,那么它应该优化到边缘。

您可以使用非常高效的算法,但在优化缓存使用之前,它的速度还不够快。它可以大大提升您的数据缓存性能。这意味着CPU不需要从RAM获取字节,它知道它们。要实现这一点,您应该尝试将数据存储在彼此之间,您的可执行文件和数据大小应该是最小的,并尝试使用尽可能少的指针(使用静态全局固定大小的数组)。

如果你使用指针,你会不断跳入内存,你的CPU每次都需要重新加载缓存。 OOP代码充满了指针:每个对象都由其内存地址存储。你可以在任何地方调用new,这会使你的对象在整个内存中传播,这使得缓存优化几乎不可能(除非你有一个分配器或垃圾收集器使事物彼此靠近)。您可以调用回调和虚函数。编译器通常不能内联虚函数,虚函数调用相对较慢(跳转到VMT,获取虚函数的地址,调用它[这涉及在堆栈上推送参数和局部变量,执行函数然后弹出一切])。当你的循环从0到1000000每秒25次运行时,这很重要。通过使用过程样式,没有虚函数,优化可以内联那些热循环中的所有内容。

答案 7 :(得分:4)

如果项目太小以至于它将包含在一个类中并且不会被使用很长时间,我会考虑使用函数。或者,如果您使用的语言不支持OO(例如c)。

答案 8 :(得分:3)

这两个概念并不相互排斥,很可能你会将PP与OOP结合使用,我看不出如何将它们隔离开来。

答案 9 :(得分:3)

  

“面向对象语言的问题在于它们带有所有这些隐含的环境,它们随身携带。你想要一个香蕉,但你得到的是拿着香蕉和整个丛林的大猩猩。” - Joe Armstrong

你想要丛林吗?

答案 10 :(得分:3)

我认为OOP的适用性更多地取决于您所在的主题领域而不是项目的大小。有一些主题领域(CAD,模拟建模等),其中OOP自然地映射到所涉及的概念。但是,有很多其他领域的映射最终变得笨拙和不协调。许多使用OOP的人似乎都花了很多时间试图将方钉钉入圆孔中。

OOP有它的位置,但程序编程,函数式编程等也是如此。看看你想要解决的问题,然后选择一个编程范例,它允许你编写最简单的程序来解决它。

答案 11 :(得分:2)

您的部分答案取决于您使用的语言。我知道在Python中,将过程代码移动到类或更正式的对象中非常简单。

我的一种启发式方法是基于情况的“状态”。如果该过程污染了命名空间,或者可能影响全局状态(以不良或不可预测的方式),那么将该函数封装在对象或类中可能是明智之举。

答案 12 :(得分:2)

对于某种类型的程序,程序程序可以更简单。通常,这些是类似脚本的简短程序。

答案 13 :(得分:2)

考虑这种情况: 你的代码不是OO。您的整个程序中都有数据结构和许多功能,可以在数据结构上运行。每个函数都将数据结构作为参数,并根据数据结构中的“data_type”字段执行不同的操作。

如果一切正常并且不会改变,谁会关心它是否是OO?它正在发挥作用。完成。如果你能够在程序上更快地写到这一点,那么可能就是这样。

但你确定它不会被改变吗?假设您可能会添加新类型的数据结构。每次添加希望对这些函数进行操作的新数据结构类型时,都必须确保找到并修改这些函数中的每一个以添加新的“else if”大小写以检查并添加所需的行为影响新类型的数据结构。随着程序越来越大,越来越复杂,这种痛苦也随之增加。这样的可能性越大,你采用OO方法就越好。

并且 - 你确定它没有错误吗?更多涉及的切换逻辑在测试每个代码单元时产生更多复杂性。通过多态方法调用,该语言为您处理切换逻辑,并且每种方法都可以更简单,更直接地进行测试。

答案 14 :(得分:2)

OOP的目标之一是使可重用性更容易,但它不是唯一的目的。学习有效使用对象的关键是设计模式。

我们都习惯了算法的概念,它告诉我们如何组合不同的过程和数据结构来执行常见的任务。相反,请看四人帮的设计模式,了解如何组合对象以执行常见任务。

在我学习设计模式之前,除了作为超类型结构之外,我对如何有效地使用对象几乎一无所知。

请记住,实现接口同样重要,如果不比继承更重要的话。在当天,C ++领先于面向对象编程的示例,与继承(虚函数等)相比,使用接口变得模糊。 C ++ Legacy意味着更多的重点放在重复使用各种教程和广泛的概述中的行为。从那时起,Java,C#和其他语言已经将界面转移到了更多的焦点上。

哪些界面非常适合精确定义两个对象如何与每个对象进行交互。它不是关于重用行为。事实证明,我们的许多软件都是关于不同部分如何相互作用的。因此,使用界面比尝试制作可重用组件提供了更多的生产力提升。

请记住,像许多其他编程思想一样,对象是一种工具。您必须充分判断它们对您的项目的效果如何。对于我的金属切削机床的CAD / CAM软件,有一些重要的数学函数没有放在对象中,因为它们没有理由放在对象中。相反,它们从库中暴露出来并被需要它们的对象使用。然后有一些数学函数被面向对象,因为它们的结构自然导致这种设置。 (获取点列表并将其转换为几种不同类型的切割路径)。再次使用你最好的判断。

答案 15 :(得分:1)

如果你在编程时“想到OO”,那么我不确定是否有必要问“何时应该回复程序编程?”这相当于向java程序员询问他们不能做什么,因为java需要类。 (Ditto .NET语言)。

如果你必须努力在程序上超越思考,那么我建议你询问如何克服这个问题(如果你愿意的话);否则留在程序上。如果进入OOP模式需要花费很多精力,那么无论如何你的OOP代码都可能无法正常工作(直到你进一步了解学习曲线。)

答案 16 :(得分:1)

我总是以自上而下的方式开始设计,而在顶级部分则更容易用OOP术语来思考。但是,当需要编写一些特定的小部件时,只需编写程序编程就可以提高效率。 OOP在设计和塑造项目方面很酷,因此可以应用divide-et-impera范例。但是你不能在代码的每个方面应用它,因为它是一种宗教信仰:)

答案 17 :(得分:1)

我相信Grady Booch曾经说过,你真的开始从OOP那里获得10000多行代码。

但是,我总是采用OO方式。即使是200行。从长远来看,这是一种优越的方法,而开销只是一个被高估的借口。所有重要的事情都从小事做起。

答案 18 :(得分:0)

我的两分钱......

程序编程的优点

  • 简单的设计(快速的概念证明,与戏剧性的战斗 动态要求)
  • 简单的项目间沟通
  • 当时间顺序重要时自然
  • 运行时开销减少

程序代码越多越好,功能就越接近。 FP的优点众所周知。

答案 19 :(得分:0)

到目前为止,将面向对象用于 DRY 和封装的论点只是增加了不必要的复杂性,因为它的隐含性以及类可以继承许多属性和方法的层数。< /p>

更不用说设计一个好的 OO 真的很难,因为你最终会添加不相关/不必要的东西,这些东西将在继承它们的整个类层中被继承。如果一个父类变得混乱,整个代码库就会变得混乱,这真的很糟糕。并被重构。

还有一个事实,即那些继承的属性并不特别适合继承它的类的用例,需要重写。而对于那些根本不需要它们的人来说,只是无缘无故地拥有它们。

对于不需要共享的东西,肯定有抽象属性。但你最终不得不在所有试图继承它们的实例中实现它们。

这种继承太神奇了,而且变得很危险。

但我认为 OO 能够很好地执行应该可用的内容。但话又说回来,太强大了,真的很容易被误用。

在我看来,final class 应该是默认的。是否允许继承需要慎重选择。

答案 20 :(得分:0)

您可以在这两个概念中编写错误的软件。尽管如此,复杂的软件在OO语言中比在程序中更容易编写,理解和维护。我用过程语言(Oracle PL / SQL)编写了高度复杂的ERP应用程序,然后切换到OOP(C#)。它现在仍然是一股清新的空气。

答案 21 :(得分:0)

恕我直言,OOP的长期利益超过了短期内节省的时间。

就像AZ说的那样,以程序的方式使用OOP(我做了很多),是一个很好的方法(对于较小的项目)。项目越大,你应该采用的OOP越多。

答案 22 :(得分:0)

大多数研究发现OO代码比程序代码更简洁。如果你看看用C ++重写现有C代码的项目(不是我必须建议的,BTW),你通常会看到代码大小减少50%到75%。

所以答案是 - 总是使用OO!