OOP有什么意义?

时间:2008-08-23 14:40:29

标签: language-agnostic oop

据我所知,尽管花费了数百万或数十亿美元用于OOP教育,语言和工具,但OOP并未提高开发人员的工作效率或软件可靠性,也没有降低开发成本。很少有人在任何严格意义上使用OOP(很少有人坚持或理解LSP等原则);人们对问题域建模所采用的方法几乎没有统一性或一致性。这个课程常常仅用于语法糖;它将记录类型的函数放入它们自己的小名称空间中。

我为各种各样的应用程序编写了大量代码。虽然有些地方真正可替代的子类型在应用程序中发挥了重要作用,但这些都非常特殊。总的来说,虽然谈到“重复使用”的口号很多,但事实是,除非一段代码完全你想要它做什么,否则很少有成本效益-使用”。将类设计为以正确方式进行扩展是非常困难的,因此扩展的成本通常非常高,以至于“重用”根本就不值得。

在许多方面,这并不让我感到惊讶。现实世界不是“OO”,OO隐含的想法 - 我们可以通过某种类别分类来模拟事物 - 在我看来非常根本性的缺陷(我可以坐在桌子上,树桩上,汽车引擎盖上)某人的膝盖 - 但不是其中一个 - 一把椅子)。即使我们转向更抽象的领域,OO建模通常也很困难,违反直觉,最终无益(考虑圆/椭圆或正方形/矩形的经典例子)。

那我在这里错过了什么? OOP的价值在哪里?为什么所有的时间和金钱都无法使软件变得更好?

45 个答案:

答案 0 :(得分:119)

  

现实世界不是“OO”,OO隐含的想法 - 我们可以使用某种类别分类法对事物进行建模 - 在我看来基本上是有缺陷的

虽然这是事实并且已经被其他人观察到(采用STL的发明者Stepanov),其余的都是无稽之谈。 OOP可能存在缺陷,它肯定不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法。当然,这只适用于“好”的OOP设计。邋design的设计不会带来任何好处。但是好的,解耦设计可以使用OOP很好地建模,而不是很好地使用其他技术。

有更好的,更通用的模型(Haskell's type model浮现在脑海中)但这些模型通常也更复杂和/或难以有效实施。 OOP是极端之间的良好平衡。

答案 1 :(得分:45)

OOP不是关于创建可重用的类,而是关于创建可用类。

答案 2 :(得分:42)

  

经常使用该课程   只是因为它的语法糖;它   将函数放在记录类型中   进入自己的小命名空间。

是的,我觉得这也太普遍了。这不是面向对象的编程。它是基于对象的编程和以数据为中心的编程。在与OO Languages合作的10年中,我看到人们大多数都在进行基于对象的编程。 OBP很快就崩溃了,因为你基本上得到了两个词中最糟糕的一个:1)程序编程没有遵循经过验证的结构化编程方法和2)OOP而不遵守经过验证的OOP方法。

完成OOP是一件很美好的事情。这使得很容易解决的问题非常困难,而且对于那些没有经验的人(不要试图在那里听起来很夸张),它几乎看起来像魔术。话虽这么说,OOP只是编程方法工具箱中的一个工具。它不是所有方法的全部。它恰好适合大型商业应用程序。

大多数使用OOP语言的开发人员都在使用他们日常使用的框架和类型中完成的OOP示例,但他们并没有意识到这一点。下面是一些非常简单的例子:ADO.NET,Hibernate / NHibernate,Logging Frameworks,各种语言集合类型,ASP.NET堆栈,JSP堆栈等等......这些都是在代码库中严重依赖OOP的东西。 / p>

答案 3 :(得分:32)

重用不应该是OOP的目标 - 或任何其他范例。

重用是良好设计和适当抽象级别的副作用。代码通过做一些有用的事情来实现重用,但却没有做到使其变得不灵活。代码是否为OO并不重要 - 我们重用可行的方法,而不是自己做的微不足道。这是实用主义。

将OO视为通过继承进行重用的新方法存在根本缺陷。正如您所注意到的那样,LSP违规很多。相反,OO被恰当地认为是管理问题域复杂性的一种方法。目标是随着时间的推移系统的可维护性。实现这一目标的主要工具是将公共接口与私有实现分离。这允许我们使用编译器强制执行的规则,例如“只应使用...修改”,而不是代码审查。

使用这个,我相信你会同意,允许我们创建和维护非常复杂的系统。这有很多价值,在其他范例中并不容易。

答案 4 :(得分:28)

对宗教进行抨击,但我会说你正在描绘现代OOP状态的过于严峻的画面。我认为它实际上已经降低了成本,使大型软件项目易于管理,等等。这并不意味着它解决了软件混乱的根本问题,并不意味着普通开发人员是OOP专家。但是将功能模块化为对象组件肯定会减少世界上意大利面条代码的数量。

我可以想到几十个我头顶的图书馆,它们可以重复使用,节省了无法计算的时间和金钱。

但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。

答案 5 :(得分:24)

没有经验证据表明,面向对象是人们思考世界的一种更自然的方式。在编程心理学领域有一些工作表明,OO不是比其他方法更合适。

  

面向对象的表示似乎没有普遍的可用性或更少的可用性。

     

仅仅采用OO方法并要求开发人员使用这些方法是不够的,因为这可能会对开发人员的工作效率以及开发的系统质量产生负面影响。

来自2000年10月ACM通讯的“关于OO表示的可用性”。文章主要将OO与面向过程的方法进行比较。有很多关于如何使用OO方法“思考”的人的研究(Int.J. of Human-Computer Studies 2001,issue 54,或Human-Computer Interaction 1995,vol.10,OO研究的整个主题),从我读到的内容来看,没有任何迹象表明OO方法具有某种自然性,使其比传统的程序方法更适合。

答案 6 :(得分:21)

  

我认为使用不透明的上下文对象(Win32中的HANDLEs,C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它确实没有在程序代码中也可以找到比封装更多的封装;我很难看出这对OOP来说是多么特别。

HANDLE s(以及WinAPI的其余部分) OOP! C不能很好地支持OOP,因此没有特殊的语法,但这并不意味着它不使用相同的概念。从各个方面来说,WinAPI都是面向对象的框架。

请注意,这是涉及OOP或替代技术的每一次讨论的问题:没有人清楚定义,每个人都在谈论其他事情,因此无法达成共识。对我来说似乎是浪费时间。

答案 7 :(得分:14)

它是一种编程范例。旨在让我们的凡人更容易将问题分解成更小,更实用的部分..

如果你没有发现它有用..不要使用它,不要支付培训费用并且要开心。

另一方面,我发现它很有用,所以我会:)

答案 8 :(得分:14)

相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致 的概念将接口从实现中分离出来。这些是非常重要的概念,也是建立框架的基础,以不同的方式和更好的(我认为)方式思考程序设计。你不能真正反对这些属性 - 没有做出权衡,它总是一种更简洁的方式来模块化。

OOP的其他方面,包括继承和多态,也很重要,但正如其他人所提到的,那些通常被过度使用。即:有时人们使用继承和/或多态,因为他们可以,而不是因为他们应该。它们是强大的概念,非常有用,但需要明智地使用,而不是OOP的自动获胜优势。

相对于重复使用。我同意重复使用已超过OOP。这是明确定义的对象的可能的副作用,通常是更原始的/通用的类,并且是封装和信息隐藏概念的直接结果。它可能更容易被重用,因为定义良好的类的接口只是更简单,有点自我记录。

答案 9 :(得分:12)

OOP的问题在于它被超卖了。

正如Alan Kay最初设想的那样,它是原始数据和全球惯例的先前实践的一个很好的替代方案。

然后一些管理顾问类型锁定它并将其作为软件的救世主出售,并且类似于旅鼠,学术界和工业界随之而来。

现在,在其他好的想法被超卖之后,他们正在蹒跚而行,例如功能性编程。

那么我会做些什么呢?很多,我写了一本关于此的书。 (它已经绝版 - 我没有得到一分钱,但你仍然可以获得副本。)Amazon

我的建设性答案是将编程看作是在现实世界中对事物进行建模的一种方式,而是作为编码要求的一种方式。

这是非常不同的,并且基于信息理论(在任何人都能理解的水平上)。它说编程可以看作是定义语言的过程,这样做的技巧对于良好的编程至关重要。

它提升了特定领域语言(DSL)的概念。它强烈赞同DRY(不要重复自己)。它给代码生成带来了很大的好感。与现代应用相比,它使软件的数据结构大大减少。

它试图重新激发前进的道路在于创造性的想法,并且即使是被广泛接受的想法也应该受到质疑。

答案 10 :(得分:11)

是的,OOP没有解决我们所有的问题,对不起。然而,我们正致力于解决所有这些问题的SOA。

答案 11 :(得分:11)

  
    

HANDLEs(以及WinAPI的其余部分)是OOP!

  
     但是,他们是吗?它们不是可继承的,它们肯定不是可替代的,它们缺乏定义明确的类......我认为它们远远没有“OOP”。

您是否曾使用WinAPI创建窗口?然后你应该知道你定义了一个类(RegisterClass),创建了一个实例(CreateWindow),调用了虚方法(WndProc)和基类方法({{1} }) 等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。

句柄可能不是可继承的,但是Java中有DefWindowProc。他们不缺课,他们 是该课程的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。

答案 12 :(得分:10)

根据我审查代码和项目设计的经验,OOP的价值还没有完全实现,因为很多开发人员已经没有在他们的脑海中正确地概念化面向对象模型。因此,他们不使用OO设计编程,经常继续编写自上而下的程序代码,使类成为一个非常 flat 设计。 (如果你甚至可以在第一时间称之为“设计”)

观察同事了解抽象类或接口的含义是非常可怕的,更不用说正确设计继承层次结构以满足业务需求。

然而,当存在良好的OO设计时,阅读代码并看到代码自然地落入直观的组件/类中只是纯粹的快乐。我一直认为系统架构和设计就像设计公司中的各个部门和员工工作一样 - 所有这些都是为了完成宏观方案中的某项工作,从而发挥推动组织/系统前进所需的协同作用。 / p>

不幸的是,这当然非常罕见。就像世界上设计精美的设计与可怕设计的物理对象的比例一样,软件工程和设计也是如此。拥有良好的工具并不一定能带来良好的实践和结果。

答案 13 :(得分:10)

OOP非常适合编程GUI“小部件”等内部计算机结构,其中例如SelectList和TextBox可能是Item的子类型,它具有常见的方法,如“move”和“resize”。

麻烦的是,我们90%的人在业务领域工作,我们正在处理发票,员工,工作,订单等业务概念。这些非常适合OOP,因为“对象”更加模糊,可根据业务重新设计等进行更改。

最糟糕的情况是OO热情地应用于数据库,包括对SQL数据库的恶劣OO“增强” - 除非数据库新手认为他们必须是正确的做事方式,因为他们是较新的,否则会被正确忽略。

答案 14 :(得分:9)

也许帽子,膝盖或树不是椅子,但它们都是ISittable。

答案 15 :(得分:8)

  

我认为那些现实世界的事物是对象

你呢?

发票有哪些方法?等一下。它不能自己付费,它不能自己发送,它无法与供应商实际交付的项目进行比较。它根本没有任何方法;它是完全惰性和无功能的。它是一种记录类型(结构,如果你愿意),而不是一个对象。

同样你提到的其他事情。

仅仅因为某些东西是真实的并不能使它成为OO意义上的对象。 OO对象是状态和行为的特殊耦合,可以自行行动。这不是现实世界中丰富的东西。

答案 16 :(得分:7)

首先,观察结果有点草率。我没有关于软件生产力的数据,也没有充分的理由相信它没有上升。此外,由于有许多人滥用OO,即使OO是花生酱以来最好的东西,使用OO也不一定能提高生产率。毕竟,一个不称职的脑外科医生可能会比没有人更糟糕,但一个称职的脑外科医生可能是非常宝贵的。

话虽如此,OO是一种不同的排列方式,将过程代码附加到数据上,而不是让程序代码对数据进行操作。这应该至少是一个小胜利,因为有些情况下OO方法更自然。没有什么从用C编写的程序API停止任何++的,毕竟,所以提供对象的选项,而不是使语言更加灵活。

此外,OO做得非常好:它允许旧代码自动调用新代码,无需更改。如果我有一个程序化管理的东西代码,我添加的那相似但不完全相同到一个较早的一件事一个新的排序,我必须要改变的程序代码。在OO系统中,我继承了功能,改变了我喜欢的内容,并且由于多态性而自动使用新代码。这增加了变化的局部性,这是一件好事。

缺点是良好的OO不是免费的:需要时间和精力来正确学习它。由于它是一个重要的流行词,因此有很多人和产品做得很差,只是为了做到这一点。这不是更容易设计多好的程序API良好的类接口,并有种种容易犯错误(如深的类层次结构)。

将其视为一种不同的工具,通常不一定更好。比如锤子和螺丝刀。也许我们最终会退出软件工程的实践,因为他们知道使用哪种扳手敲击螺钉。

答案 17 :(得分:7)

我在过去9年左右一直在编写OO代码。除了使用消息传递之外,我很难想象其他方法。我看到的主要好处完全符合CodingTheWheel所说的:模块化。 OO自然地引导我从模块化组件构建我的应用程序,这些组件具有干净的界面和明确的职责(即松散耦合,高度内聚的代码以及明确的关注点分离)。

我认为OO崩溃的地方是人们创建深层嵌套的类heirarchies。这可能导致复杂性。然而,将共同的功能分解为基类,然后在其他后代类中重用它是一件非常优雅的事情,恕我直言!

答案 18 :(得分:6)

对我来说,OOP语法本身有很多价值。使用试图表示真实事物或数据结构的对象通常比尝试使用一堆不同的扁平(或“浮动”)函数对相同数据执行相同操作更有用。对具有良好OOP的事物有一定的自然“流动”,这对于长期阅读,编写和维护更有意义。

Invoice实际上并不一定是具有可以自己执行的函数的“对象” - 对象实例只是为了对数据执行函数而不必知道实际上是什么类型的数据那里。可以成功调用函数“invoice.toJson()”,而无需知道“发票”是什么类型的数据 - 结果将是Json,无论它来自数据库,XML,CSV甚至是另一个JSON对象。使用过程函数,你突然间必须更多地了解你的数据,并最终得到像“xmlToJson()”,“csvToJson()”,“dbToJson()”等函数。它最终变成一个完整的混乱和一个如果你改变了基础数据类型,那就太麻烦了。

OOP的目的是通过抽象来隐藏实际的实现。要实现该目标,您必须创建一个公共接口。为了使您的工作更容易创建公共接口并保持干净,您必须使用抽象类,继承,多态和设计模式等概念。

所以对我来说,OOP真正的首要目标是使未来的代码维护和更改变得更容易。但即使超越这一点,当以程序代码永远无法完成的方式正确完成时,它可以真正简化很多事情。如果它与“真实世界”不匹配并不重要 - 无论如何,用代码编程都不会与现实世界的对象交互。 OOP只是一种工具,可以让我的工作更轻松,更快捷 - 我会在任何一天都去做。

答案 19 :(得分:6)

@Konrad

  

OOP可能存在缺陷,它当然不是银弹,但它使大规模应用程序变得更加简单,因为它是减少依赖性的好方法

这就是教条。在这方面,我没有看到OOP明显优于旧程序编程的原因。每当我进行程序调用时,我都会将自己从实现的细节中分离出来。

答案 20 :(得分:6)

@Sean

  

然而,将共同的功能分解为基类,然后在其他后代类中重用它是一件非常优雅的事情,恕我直言!

但是,无论如何,“程序性”开发人员已经这样做了几十年。语法和术语可能不同,但效果相同。 OOP比“在基类中重复使用常用功能”还要多,我甚至可能会说很难将其描述为OOP;从不同的代码位调用相同的函数是一种与子过程本身一样古老的技术。

答案 21 :(得分:5)

@Jeff

  

相对于直接的程序编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致了类的概念,它将接口从实现中分离出来。

哪个隐藏的实现更多:C ++的iostreams,或C的FILE * s?

我认为使用不透明的上下文对象(Win32中的HANDLEs,C中的FILE *,用来命名两个着名的例子 - 地狱,HANDLEs生活在内核模式障碍的另一边,它确实没有在程序代码中也可以找到比封装更多的封装;我很难看出这对OOP来说是多么特别。

我想这可能是我努力看到好处的原因之一:明显优秀的部件并不是OOP特有的,而OOP特有的部件显然不是很好! (这并不是说它们一定是坏的,而是我没有看到它们广泛适用且始终有益的证据。)

答案 22 :(得分:5)

在我读过的唯一一个开发博客中,由Joel-On-Software-Founder-of-SO家伙,我很久以前就读到OO不会导致生产力提高。自动内存管理。凉。谁可以拒绝这些数据?

我仍然相信OO对于非OO来说,使用函数进行编程是为了编写所有内联函数。

(我应该知道,当我开始使用GWBasic时。)当你重构时使用函数的代码,variable2654变为您所使用的方法的variable3。或者,更好的是,它有一个您可以理解的名称,如果函数很短, strong>它被称为value,这足以让人完全理解。

当没有函数的代码成为带方法的代码时,你可以删除数英里的代码。

当您将代码重构为真正的OO时,bcqZ变为thisthis,{ {1}}和this。由于我不相信使用this关键字,因此您可以删除数英里的代码。实际上,即使您使用this,也可以这样做。



我不认为OO是天生的比喻。

我认为语言也不是一个自然的比喻,我也不认为福勒的“气味”比说“这个”更好代码味道不好。“也就是说,我认为面向对象并不是关于自然隐喻,而那些认为对象刚出现在你身上的人基本上忽略了这一点。 您定义对象Universe,和更好的对象Universe会导致代码更短,更易于理解,效果更好,或者所有这些(以及我忘记的一些标准)。我认为使用客户/域的自然对象作为编程对象的人缺乏重新定义宇宙的能力。

例如,当您使用机票预订系统时,您所谓的预订可能根本不符合法律/商业预订。



一些基本概念是非常酷的工具

我认为大多数人都夸大了整体“当你有锤子时,他们都是钉子”的东西。我认为硬币/镜子的另一面也是如此:当你有一个像多态/继承这样的小工具时,你就会开始找到适合手套/袜子/隐形眼镜的用途。 OO的工具非常强大。我认为单身继承绝对是必要的,对于那些不被带走的人,我自己multi-inheritance software not withstanding.



OOP有什么意义?

我认为这是处理绝对庞大代码库的好方法。我认为它可以让你组织和重新组织你的代码,并为你提供一种语言(超出你正在使用的编程语言),并以一种非常自然和易于理解的方式模块化代码。

OOP注定会被大多数开发者误解这是因为它是一个令人大开眼界的过程,就像生活一样:你越来越了解OO的经验,并开始避免某些模式并雇佣其他人聪明。最好的例子之一是你不再使用你不能控制的类的继承,而是更喜欢 Facade 模式。



关于你的迷你论文/问题

我确实想提一下你是对的。在大多数情况下,可重用性是一个梦想。以下是Anders Hejilsberg关于该主题的引用(精彩)from here

  

如果你问初学程序员   他们经常写一个日历控件   想想,“哦,我要去   写下世界上最好的日历   控制!它将是多态的   关于日历的种类。   它将有显示器和mungers,   而这,那个和另一个。“他们   需要发送日历应用程序   两个月。他们把这一切都放了   基础设施到位   控制,然后花两天时间   写一个糟糕的日历应用程序   在它的上面。他们会想,“在   下一个版本的应用程序,我   要做更多的事情。“

     

一旦他们开始思考如何   他们实际上是要实施的   所有这些其他的具体化   但是,它们的抽象设计   事实证明他们的设计是   完全错了。现在他们已经   把自己画成一个角落,然后   他们不得不扔掉整件事   出。我一遍又一遍地看到了。   我坚定地相信自己   简约。除非你真的是   要解决一般问题,   不要试图建立一个框架   解决特定问题,因为   你不知道那个框架是什么   应该看起来像。

答案 23 :(得分:5)

@CodingTheWheel

  

但是,就OOP浪费时间而言,我认为这是因为缺乏程序员培训,而且学习语言特定OOP映射的学习曲线陡峭。有些人“得到”OOP而其他人永远不会。

但是,如果这真的令人惊讶,我不知道。我认为技术上合理的方法(LSP显而易见)会使难以使用,但如果我们不使用这种方法,它会使代码变得脆弱且无法表达(因为我们不能再推理它)。而且我认为OOP引导我们采取违反直觉的结果会让人们不会惊讶于人们不会接受它。

更重要的是,由于软件对于普通人来说已经基本上难以可靠和准确地编写,我们是否真的应该赞美一种一贯教导并且难以学习的技术?如果利益是明确的,那么尽管存在困难,它可能值得坚持,但似乎并非如此。

答案 24 :(得分:4)

我完全赞同InSciTek Jeff的回答,我只想添加以下改进:

  • 信息隐藏和封装:对于任何可维护代码都至关重要。可以通过在任何编程语言中小心,不需要OO功能来完成,但这样做会使你的代码略微像OO一样。
  • 继承:有一个重要的应用程序域,所有这些OO 都是一种包含-a 关系非常适合:图形用户界面。如果您尝试在没有OO语言支持的情况下构建GUI,那么无论如何您最终都会构建类似OO的功能,并且在没有语言支持的情况下更难以且更容易出错。例如,Glade(最近)和X11 Xt(历史上)。

使用OO功能(特别是深层嵌套的抽象层次结构),当没有意义时,是没有意义的。但对于某些应用领域,确实有一点意义。

答案 25 :(得分:4)

  

您是否曾使用WinAPI创建窗口?

比我记得的次数多。

  

然后你应该知道你定义了一个类(RegisterClass),创建它的一个实例(CreateWindow),调用虚方法(WndProc)和基类方法(DefWindowProc)等等。 WinAPI甚至采用SmallTalk OOP的命名法,调用方法“消息”(Window Messages)。

然后你也会知道它没有自己的消息发送,这是一个很大的空洞。它也有糟糕的子类化。

  

句柄可能不是可继承的,但是,Java中有最终版本。他们不缺课,他们是班级的占位符:这就是“句柄”这个词的含义。看看像MFC或.NET WinForms这样的架构,很明显,除了语法之外,与WinAPI没什么不同。

它们在接口或实现中都是不可继承的,最小可替代的,并且它们与程序编码器一直在做的事情没有太大的不同。

这是真的吗? OOP的最佳位置只是......传统的程序代码? 那是最重要的事情?

答案 26 :(得分:4)

我认为最有利的OOP质量是数据隐藏/管理。但是,有很多例子都说OOP被误用了,我认为这就是混乱的地方。

仅仅因为你可以把东西变成对象并不意味着你应该。但是,如果这样做会使你的代码更有条理/更容易阅读,那么你绝对应该这样做。

OOP非常有用的一个很好的实际例子是我在我们网站上使用的“产品”类和对象。由于每个页面都是一个产品,并且每个产品都引用了其他产品,因此您所引用的数据所引用的产品会非常混乱。这个“strURL”变量是指向当前页面,主页或统计页面的链接吗?当然,您可以制作引用相同信息的各种不同变量,但proCurrentPage-> strURL更容易理解(对于开发人员而言)。

此外,将功能附加到这些页面要清晰得多。我可以做proCurrentPage-> CleanCache();其次是proDisplayItem-> RenderPromo();如果我只是调用这些函数并假设当前数据可用,谁知道会发生什么样的恶。此外,如果我必须将正确的变量传递给这些函数,我回到了为不同产品提供各种变量的问题。

相反,使用对象,我的所有产品数据和功能都很好,干净且易于理解。

然而。 OOP的一个大问题是当有人认为一切都应该是OOP时。这会产生很多问题。我的数据库中有88个表。我只有大约6个班级,也许我应该有大约10个班级。我绝对不需要88个班级。在我使用它的情况下,大多数情况下直接访问这些表是完全可以理解的,而OOP实际上会使得更难/乏味地了解正在发生的事情的核心功能。

我认为对象的混合模型在实用中是有用的和程序性的,是最有效的编码方法。遗憾的是,我们拥有所有这些宗教战争,人们主张以牺牲其他方法为代价来使用一种方法。他们都很好,他们都有自己的位置。大多数情况下,在每个较大的项目中都有两种方法的用途(在一些较小的项目中,单个对象或几个程序可能就是您所需要的全部)。

答案 27 :(得分:3)

我不像在可读性方面那样关心重用。后者意味着您的代码更容易更改。在构建软件的过程中,仅凭金就是值得的。

OO是让你的程序可读的非常有效的方法。重用或不重用。

答案 28 :(得分:2)

“现实世界不是”OO“,”

真的?我的世界充满了物体。我现在正在使用一个。我认为让软件“对象”模拟真实对象可能不是一件坏事。

对于概念性事物(如Windows,而不是真实世界的窗口,但我的计算机显示器上的显示面板)的OO设计通常会留下很多不足之处。但对于现实世界的事情,如发票,运输订单,保险索赔和什么不是,我认为那些现实世界的东西都是对象。我的桌子上有一堆,所以它们必须是真的。

答案 29 :(得分:2)

根据我在20世纪80年代中期从C / Unix(非OOP)开始的经验,然后在1990年转向C ++(OOP),然后在1996年转向Java(OOP),我发现OOP可以大大提高生产力,与我之前工作的大型非OOP程序相比,可维护性和稳健性。

我观察到的主要事情是,在非OOP应用程序中,我已经研究过复杂性似乎在应用程序的复杂性方面以指数速率增长,而在OOP应用程序中,我对复杂性的研究似乎有一个与应用程序的复杂性有关的更多线性关系。

换句话说 - 使用精心设计的OOP应用程序,你永远不会得到“OMG这个应用程序的源代码正在逐渐失控”感觉你会得到大型非OOP应用程序。

作为OOP开发人员,我不能不做的其他事情是我可以编写代码来编写应用程序问题域中存在的真实世界实体。对象具有自己的生命 - 超出任何结构(C)或记录(Pascal)在旧的OOP天数中所做的回归。

一个规定是OOP项目的总设计师必须知道他正在做什么,并且他通常需要花费更多的思考时间来获得设计,而不是实际实施它,但是“先行思考”的回报真是太神奇了。重新使用的机会或非常酷的设计优化曝光让你在办公室里打空气并做达阵......好吧,这对办公室里的其他人来说可能看起来有点奇怪但是这种热情从来没有在非OOP天:)

我已经看到了一些编写得非常糟糕的OOP代码,也许这就是你所经历的可能导致你提出问题的问题。作为90年代中期的承包商,我经常发现“OO”设计已经由一个知道课程但却不多的人开始。这是一次非常痛苦的经历,我经常发现,我在工作的头几个月以“OO”思维的不同方式教育团队。只有在每个人的大脑都经过重新布线之后,我们才能以团队的形式创造出令人敬畏的东西。

许多人发现'大脑重新布线'过程过于艰苦,痛苦或者只是太过努力,所以花费他们的生命来消除'OOP,所以你会发现很多OO仇敌,但我很高兴因为是那些让我这样的人看起来很好的人:“什么,你可以花X美元做它,它将在2个月内准备就绪,你会给我们一个可维护的代码库!!!哇,你今天能开始吗?” / p>

答案 30 :(得分:2)

OOP的目的是为程序员提供另一种方法,用于描述和向机​​器和人员传达代码问题的解决方案。其中最重要的部分是与人们的沟通。 OOP允许程序员通过OO语言中强制执行的规则来声明它们在代码中的含义。

与此主题的许多论点相反,OOP和OO概念在所有代码中都很普遍,包括非OOP语言(如C语言)中的代码。许多高级非OO程序员即使在非OO语言中也会近似于对象的特征。

将OO内置到语言中只会给程序员另一种表达方式。

编写代码的最大部分不是与机器的通信,这部分很容易,最大的部分是与人类程序员的沟通。

答案 31 :(得分:2)

这是唯一语言可移植方法,用于将变量与与之交互的函数/方法/子例程组合在一起。

答案 32 :(得分:1)

OOP有助于将接口与实现分开。您不需要使用该语言的OOP支持来从OO设计中受益。

OOP帮助极大的一个小例子:

UNIX虚拟文件系统(VFS)层使用函数指针表提供统一的接口(打开/读/写) - 非常类似于C ++虚拟表分派。

客户端使用相同的一组调用,无论他们是在与本地文件系统,远程网络文件系统(NFS)还是(今天)假文件系统(例如/ proc)进行通信。

请参阅最初的Sun论文:Vnodes:Sun UNIX中多文件系统类型的体系结构

答案 33 :(得分:1)

这已经有很多答案了,因为这是一篇很老的帖子,但我以为我会参与其中。

你提到“类分类法”有点进入子类型和多态。这一切都围绕着继承,其中鼎盛时期被认为是OOP的银弹。如今,实际上不鼓励继承和大类层次结构,即使在那些执行大量OOP的商店中也是如此。这是因为已经发现OOP的其他原理,例如封装,松散耦合,内聚力等比继承更有用。我甚至会说松散耦合是OO的原因,而不是代码重用。代码重用通常发生在方法/功能级别。我有时会在不同情况下重复使用类,但不经常这样。松耦合虽然有助于组织系统相当多。每个对象都有自己的范围,除了访问器方法或属性之外,对象中的数据不会或不应该被操纵,每个对象应该做一件简单的事情,并且应该通过简单的接口与其他对象通信。这一小撮原则有助于编写可读性,有助于隔离错误并防止您在许多不同的地方进行许多更改以改变一件事。当对象没有紧密交织在一起时,您可以在不影响其他对象的情况下更改对象。这对我来说是一个巨大的好处。继承只是偶尔有用。

代码重用仍然很重要,如果您正在复制,粘贴或重写相同的代码,即使在简单的旧程序,结构化或函数式编程中,这也是一种不好的做法。这实际上会因为重复工作,增加维护和更多错误而增加成本。

答案 34 :(得分:1)

“即使没有实际的[信息架构],也并不意味着我们没有经历或感知它。禅宗佛教徒说没有真正的”自我“,但他们仍然为孩子命名。” - 安德鲁·辛顿

答案 35 :(得分:1)

现实世界不是“OO”。现实世界并非主要由合理的作品构成。相反,它是由混乱运动的粒子组成的。地球是一种颗粒汤。人们仍然看到鸟类,树木,天空,地面,森林,池塘。 OO是关于程序组件的抽象。考虑OO来建模除了程序之外的其他东西是根本性的缺陷。

所有的金钱和时间都没能使软件变得更好,因为它无法使程序员变得更聪明,也因为它未能改变人们对软件的看法。从你使用它的意义上说,“OOP”是一个用来赚钱的流行语 白痴。是的,那些把钱投入“OOP”教育和工具的人都是白痴。那些倾向于恶作剧的人往往是白痴。

“OOP”的值是抽象,代码在同一程序中重用 。 OOP旨在用于命令式程序。

如果你从装配程序中起床。汇编是由标签和指令组成的有序对序列。汇编代码类似于'粒子汤'。现在您可以转到子程序。子程序从该标签中选择一个标签:instruction -soup,并隐藏子程序中的其余标签。随着效果代码变得更抽象,您的命名空间保持清晰。

现在,如果你认为子程序会做什么......几十年前,很少有人认为子程序在处理参数时处于最佳状态。这使他们为每个对象提供了自己的协议。协议将包含label:procedure -pairs。现在称为selector:method -pairs。程序不再直接与其他程序绑定,解释了“后期绑定” - 期限。除了保持协议(继承)的历史,这在smalltalk中形成了“面向对象”。

你已经丧失了后期绑定机制的能力,忘记了继承的含义。你还想知道你在那里失踪了什么。 “OOP的价值在哪里,为什么所有的时间和金钱都无法让软件变得更好?” - 我想你把它们塞进你的屁股里。当你尝试进行结肠镜检查时,你会发现它们。

答案 36 :(得分:1)

我们会在十年后对功能编程说同样的话吗?

答案 37 :(得分:1)

  

HANDLEs(以及WinAPI的其余部分)是OOP!

但是,他们是吗?它们不是可继承的,它们肯定不是可替代的,它们缺乏定义明确的类......我认为它们远远没有“OOP”。

答案 38 :(得分:1)

  

也许帽子,膝盖或树不是椅子,但它们都是ISittable。

是的,但只是事后。他们是ISITtable因为有人坐在他们身上。

答案 39 :(得分:1)

对我来说,OOP的价值在于缩小范围并将状态与行为分开。范围较小,代码更容易理解。

它可以在大多数语言中完成,所有这些都需要实现,这是一种状态将方法调用委托给行为的方式,以及行为进一步委托调用父行为的方式。

为了让一组类以有效的方式为域建模,没有神奇的方法。像钢琴一样,我们必须练习。 OOP是一个抽象工具,它可以帮助您以更简单的方式构建代码,但它无法为您思考和分析应用程序的域。

对我来说有用的是尽可能长时间地接近域名,同时仍然避免大多数代码重复。

答案 40 :(得分:1)

我知道我发现OOP几乎完全基于语法糖基础(封装,运算符重载,类型检查)。至于OOP的好处......我不知道。我不认为它比程序性的东西更糟糕

在较轻的一面,我的OOP讲师说OOP很重要,否则“代码会有太多的循环”。是啊。有时令人沮丧的是我每张纸支付500美元。 :(

答案 41 :(得分:0)

OOP 降低了成本,提高了效率。

当我从经典的ASP / VBScript跳到C#时,我注意到OOP带来了巨大的生产力提升。

答案 42 :(得分:0)

我同意InSciTek Jeff。即使你没有在最纯粹的意义上使用OO,封装理论也可以帮助减少潜在的结构复杂性: http://www.edmundkirwan.com

@ DrPizza

如果程序编程使用封装的好处达到相同的程度,那就好了!

答案 43 :(得分:0)

现实世界可能不是OO,但人们倾向于通过类比(抽象)而不是逻辑来学习或思考更好。

OOP不适用于计算机,但它适用于那些在没有类比的情况下找出复杂系统的程序员。我相信OOP的主要目的是使用抽象更好地组织代码,因此在不了解其他部分的情况下,程序员可以很容易地理解他/她想要处于某个级别的特定部分或整个系统的作用。

要使用抽象来组织代码,您将需要使用语言封装,继承和多态。并且SOLID OOP原则和设计模式可以在这个组织中发挥更好的作用。但我认为OOP的重点是抽象,因为人类以这种方式思考得更好。

答案 44 :(得分:0)

OOP是关于实例化的......你想要一遍又一遍地重新安装相同的东西,其活动分类略有不同。共享活动意味着共享类。

如果你不想以这种方式思考,不要做OOP。在说帕斯卡之后开始思考这个问题肯定会扭曲思维,因此很生气的程序员。

你将实例化的机器人细化到最后的差异,你不要重复一次。

每个分类差异只有1个标签/类(不是每个不同的东西!),这就是OOP的强大功能......这就是它与ai的某些超级网络类似的东西,它永远不会耗尽名称不同的东西,因为它依赖于总分布来命名。

-Magnus W。