OOP的意义是什么?
据我所知,尽管在OOP教育,语言和工具上花费了数百万或者数十亿美元,但OOP并没有提高开发人员的生产力或者软件可靠性,也没有降低开发成本。很少有人严格地使用OOP(很少有人坚持或者理解LSP等原则);人们对问题域进行建模的方法似乎几乎没有统一性或者一致性。通常,该类仅用于其语法糖。它将记录类型的函数放入它们自己的小命名空间中。
我已经为各种应用程序编写了大量代码。尽管在某些场合中,真正的可替代子类型在应用程序中发挥了重要作用,但这些情况非常例外。总的来说,尽管提供了大量的口头服务来谈论"重用",但实际情况是,除非一段代码能够完全按照意愿去做,否则几乎没有成本效益的"重用"。设计类以正确的方式进行扩展非常困难,因此扩展的成本通常很高,以至于"重用"根本就不值得。
在许多方面,这并不令我感到惊讶。现实世界不是" OO",OO中隐含的想法(我们可以用某种分类法对事物建模)在我看来从根本上来说是有缺陷的(我可以坐在桌子,树桩,汽车引擎盖上) ,某人的膝盖-但其中之一不是-椅子)。即使我们转向更抽象的领域,OO建模也常常是困难,违反直觉的,最终无济于事(请考虑圆形/椭圆形或者正方形/矩形的经典示例)。
那我在这里想念什么? OOP的价值在哪里?为什么所有的时间和金钱都无法使软件变得更好?
解决方案
回答
关于宗教,但我想说的是,我们对现代OOP的状态描绘得过于严峻。我认为这实际上降低了成本,使大型软件项目易于管理,等等。这并不意味着它已经解决了软件混乱的根本问题,也并不意味着普通的开发人员是OOP专家。但是,将功能模块化为对象组件确实减少了世界范围内的意大利面条代码。
我可以想到数十个库,这些库可以很好地重用,并且节省了无法计算的时间和金钱。
但就OOP浪费时间而言,我要说的是,由于缺乏程序员培训,再加上学习特定于语言的OOP映射的陡峭学习曲线,情况更加严峻。有些人"获得" OOP,而其他人则永远不会。
回答
The real world isn't "OO", and the idea implicit in OO--that we can model things with some class taxonomy--seems to me very fundamentally flawed
尽管这是事实,并且已经被其他人观察到(例如STL的发明者Stepanov),但其余的都是胡说八道。 OOP可能有缺陷,它当然不是灵丹妙药,但是它使大规模应用程序变得简单得多,因为这是减少依赖关系的好方法。当然,这仅适用于良好的OOP设计。马虎的设计不会带来任何优势。但是,好的分离设计可以使用OOP很好地建模,而不能使用其他技术很好地建模。
有更好,更通用的模型(会想到Haskell的类型模型),但它们通常也更复杂和/或者难以有效实施。 OOP是极端情况之间的良好折衷。
回答
最近9年来,我一直在编写OO代码。除了使用消息传递之外,我很难想象其他方法。我看到的主要好处与CodingTheWheel所说的完全一致:模块化。 OO自然地带我从具有清晰接口和明确职责的模块化组件(即松散耦合,高度内聚的代码和明确的关注点分离)构建应用程序。
我认为OO崩溃的地方是当人们创建深层嵌套的类继承关系时。这会导致复杂性。但是,将常见的功能性排除在基类之外,然后在其他子类中重用它是一件非常优雅的事情,恕我直言!
回答
@CodingTheWheel
But to the extent that OOP has been a waste of time, I'd say it's because of lack of programmer training, compounded by the steep learning curve of learning a language specific OOP mapping. Some people "get" OOP and others never will.
不过,我不知道这是否真的令人惊讶。我认为技术上合理的方法(很明显是LSP)很难使用,但是如果我们不使用这种方法,无论如何它会使代码变得脆弱且不可扩展(因为我们不再能够对此进行推理)。而且我认为OOP导致我们产生的违反直觉的结果使人们不选择它并不奇怪。
更重要的是,由于从根本上说软件对于普通人来说已经太难了,以至于无法可靠,准确地编写代码,我们是否真的应该赞颂一贯教学不善且难以学习的技术?如果收益是显而易见的,那么尽管有困难,仍然值得坚持,但是事实并非如此。
回答
@西恩
However, factoring out common finctionality into a base class, then reusing that in other descendant classes is a deeply elegant thing, IMHO!
但是"程序性"开发人员已经这样做了数十年。语法和术语可能有所不同,但是效果是相同的。 OOP不仅具有"在基类中重用通用功能"的功能,而且我什至可以说很难将其描述为OOP。从不同的代码位调用相同的函数是一种与子过程本身一样古老的技术。
回答
@康拉德
OOP may be flawed and it certainly is no silver bullet but it makes large-scale applications much simpler because it's a great way to reduce dependencies
那是教条。我没有看到什么使OOP在这方面比旧的过程编程好得多。每当我进行过程调用时,我都会使自己脱离实现的细节。
回答
"即使没有实际的[信息架构],也并不意味着我们没有经历或者感知到它。禅宗佛教徒说没有实际的自我,但他们仍然给自己的孩子起名字。"-安德鲁·欣顿
回答
它是一种编程范例。旨在使我们这些凡人可以更轻松地将问题分解为更小巧,更可行的部分。
如果我们不觉得它有用。.不要使用它,不要花钱训练并开心。
另一方面,我确实认为它很有用,所以我会:)
回答
相对于直接过程编程,OOP的第一个基本原则是信息隐藏和封装的概念。这个想法导致了将接口与实现分开的类的概念。这些是非常重要的概念,是放置框架以其他方式(更好)思考程序设计的基础。我们不能真正反对那些属性,而无需权衡取舍,它始终是一种更干净的模块化方式。
OOP的其他方面(包括继承和多态性)也很重要,但是正如其他人提到的那样,这些方面经常被过度使用。即:有时人们使用继承和/或者多态性是因为他们可以这样做,而不是因为他们应该拥有。它们是功能强大的概念,并且非常有用,但是需要明智地使用它们,而不是OOP的自动取胜优势。
相对于重复使用。我同意重复使用已超出OOP的销售标准。这是定义良好的对象(通常是更多原始/通用类)的可能的副作用,并且是封装和信息隐藏概念的直接结果。由于定义良好的类的接口更加简单明了并且具有一定的自我记录性,因此重新使用可能会更容易。
回答
@杰夫
Relative to straight procedural programming, the first fundamental tenet of OOP is the notion of information hiding and encapsulation. This idea leads to the notion of the class that seperates the interface from implementation.
哪个具有更隐藏的实现:C ++的iostream或者C的FILE * s?
我认为使用不透明的上下文对象(在Win32中为HANDLE,在C中为FILE * s,举两个著名的例子-地狱,HANDLE位于内核模式屏障的另一侧,但实际上并没有得到在过程代码中也发现了比封装更多的东西)。我正在努力查看这对OOP有何特殊之处。
我想这可能就是我努力查看好处的部分原因:显然良好的部分并非特定于OOP,而特定于OOP的部分显然并不好! (这并不是说它们一定是不好的,而是我没有看到证据表明它们广泛适用并且始终如一)。
回答
OOP降低了成本,并提高了效率。
当我从经典的ASP / VBScript跳到CI时,由于OOP,生产力大大提高了。
回答
I think the use of opaque context objects (HANDLEs in Win32, FILE*s in C, to name two well-known examples--hell, HANDLEs live on the other side of the kernel-mode barrier, and it really doesn't get much more encapsulated than that) is found in procedural code too; I'm struggling to see how this is something particular to OOP.
" HANDLE"(以及WinAPI的其余部分)是OOP! C对OOP的支持不是很好,因此没有特殊的语法,但这并不意味着它不使用相同的概念。从任何意义上讲,WinAPI都是面向对象的框架。
瞧,这是涉及OOP或者替代技术的每次讨论的麻烦:没有人清楚定义,每个人都在谈论其他事情,因此无法达成共识。对我来说似乎是在浪费时间。
回答
HANDLEs (and the rest of the WinAPI) is OOP!
他们是吗?它们是不可继承的,它们当然不能被替代,它们缺少定义明确的类……我认为它们与" OOP"还差得很远。
回答
HANDLEs (and the rest of the WinAPI) is OOP!
他们是吗?它们是不可继承的,它们当然不能被替代,它们缺少定义明确的类……我认为它们与" OOP"还差得很远。
我们是否曾经使用WinAPI创建过窗口?然后我们应该知道定义了一个类(RegisterClass),创建它的实例(CreateWindow),调用虚拟方法(WndProc)和基类方法(DefWindowProc)等。 WinAPI甚至从SmallTalk OOP中获取术语,调用方法消息(窗口消息)。
句柄可能不是可继承的,但是Java中有" final"。他们不缺少一个类,他们是该类的占位符:这就是handle这个词的意思。查看MFC或者.NET WinForms之类的体系结构,很明显,除了语法之外,与WinAPI并没有什么不同。
回答
All too often, the class is used simply for its syntactic sugar; it puts the functions for a record type into their own little namespace.
是的,我也觉得这太普遍了。这不是面向对象的编程。它是基于对象的编程和以数据为中心的编程。在使用面向对象语言的10年中,我看到人们主要在进行基于对象的编程。 OBP很快就会崩溃,恕我直言,因为我们本质上是两个词中最糟糕的一个:1)不遵循成熟的结构化编程方法的过程编程,以及2)不遵循成熟的OOP方法的OOP。
正确的OOP是一件美丽的事情。它使非常困难的问题易于解决,而且对于刚开始的人(不要试图在那里吹牛),它几乎看起来像是魔术。就是说,OOP只是编程方法论工具箱中的一种工具。它不是全部结束的方法。它恰好非常适合大型企业应用程序。
大多数使用OOP语言工作的开发人员都在利用在日常使用的框架和类型中正确完成的OOP示例,但他们只是不了解。这里有一些非常简单的示例:ADO.NET,Hibernate / NHibernate,日志记录框架,各种语言集合类型,ASP.NET堆栈,JSP堆栈等...这些都是在其代码库中严重依赖OOP的东西。
回答
Have you ever created a window using WinAPI?
比我想念的要多得多。
Then you should know that you define a class (RegisterClass), create an instance of it (CreateWindow), call virtual methods (WndProc) and base-class methods (DefWindowProc) and so on. WinAPI even takes the nomenclature from SmallTalk OOP, calling the methods “messages” (Window Messages).
然后,我们还将知道它不会自行发送消息,这是一个很大的空白。它还具有糟糕的子类化。
Handles may not be inheritable but then, there's final in Java. They don't lack a class, they are a placeholder for the class: That's what the word “handle” means. Looking at architectures like MFC or .NET WinForms it's immediately obvious that except for the syntax, nothing much is different from the WinAPI.
它们在接口或者实现上都不能继承,只能被最小程度地替代,并且与程序编码器从此永远做着没有本质上的区别。
真的是这样吗? OOP的最好方面只是...传统的过程代码?那很重要吗?
回答
OOP并不是要创建可重用的类,而是要创建可用的类。
回答
没有经验证据表明面向对象是人们思考世界的一种更自然的方式。编程心理学领域的一些工作表明,OO在某种程度上并不比其他方法更合适。
Object-oriented representations do not appear to be universally more usable or less usable. It is not enough to simply adopt OO methods and require developers to use such methods, because that might have a negative impact on developer productivity, as well as the quality of systems developed.
摘自2000年10月ACM通讯的"关于OO表示的可用性"。文章主要比较OO与面向过程的方法。关于使用面向对象方法"思考"的人们的工作方式有很多研究(Int。J. of Human-Computer Studies 2001年,第54期或者Human-Computer Interaction 1995,第10卷以面向对象研究为主题),从我的阅读中,没有什么可以表明OO方法的某种自然性,使其比传统的过程方法更适合。
回答
根据我回顾过的代码和项目设计的经验,OOP的价值并未完全实现,因为许多开发人员尚未在他们脑海中正确地概念化面向对象的模型。因此,他们没有使用OO设计进行编程,而是经常继续编写自上而下的过程代码,从而使类成为一个非常平坦的设计。 (如果我们甚至可以首先将其称为"设计")
观察到很少有同事知道什么是抽象类或者接口,这真是令人恐惧,更不用说正确设计适合业务需求的继承层次结构了。
但是,当存在良好的OO设计时,仅是阅读代码并看到代码自然地融入到直观的组件/类中,这绝对是一件乐事。我一直认为系统体系结构和设计就像设计公司中各个部门和员工的工作一样,都是为了在宏伟的事情中完成某些工作,并产生推动组织/系统前进所需的协同作用。
当然,不幸的是,这种情况很少见。就像世界上设计精美的实体对象与设计糟糕的物理对象所占的比例一样,在软件工程和设计方面也可以说得差不多。拥有好的工具并不一定会带来好的做法和结果。
回答
也许引擎盖,膝盖或者树不是椅子,但它们都是可以坐的。
回答
Maybe a bonnet, lap or a tree is not a chair but they all are ISittable.
是的,但只能事后证明。它们很容易坐下,因为有人坐在上面。
回答
我知道我发现OOP仅在语法糖的基础上非常有用(封装,运算符重载,类型检查)。至于OOP的好处...我不知道。我认为这没有程序上的问题要糟。
在较轻松的方面,我的OOP讲师说OOP非常重要,因为否则"代码将有太多循环"。是的。有时令人沮丧的是我每张纸要付500美元。 :(
回答
我完全同意InSciTek Jeff的回答,我将添加以下改进:
- 信息隐藏和封装:对于任何可维护的代码而言至关重要。可以通过谨慎使用任何编程语言来完成,不需要OO功能,但是这样做会使代码有点像OO。
- 继承:在一个重要的应用程序域中,所有那些OO类型和包含关系都非常适合:图形用户界面。如果我们尝试在不提供OO语言支持的情况下构建GUI,则无论如何都将最终构建类似OO的功能,并且在没有语言支持的情况下更加困难且容易出错。例如Glade(最近)和X11 Xt(历史上)。
在没有意义的情况下使用OO功能(尤其是深度嵌套的抽象层次结构)毫无意义。但是对于某些应用程序领域,确实有一点。
回答
重用不应该是OOP或者其他任何范式的目标。
重用是良好设计和适当抽象水平的副作用。代码通过做一些有用的事情来实现重用,但是这样做并不能使它变得不灵活。代码是否为OO无关紧要,我们可以重用有效的方法,而不是琐碎的工作。那是实用主义。
OO作为通过继承重用的一种新方法的思想从根本上是有缺陷的。如我们所见,LSP违例比比皆是。取而代之的是,将OO正确地视为一种管理问题域复杂性的方法。目标是随着时间的推移系统的可维护性。实现此目的的主要工具是将公共接口与私有实现分离。这使我们拥有由编译器强制执行的规则,例如"仅应使用...进行此操作",而不是代码检查。
我相信我们会同意使用此工具,使我们能够创建和维护非常复杂的系统。这样做有很多价值,在其他范式中不容易做到。
回答
我相信OOP最有益的品质是数据隐藏/管理。但是,有很多例子误用了OOP,我认为这是造成混淆的地方。
仅仅因为我们可以将某些东西变成对象并不意味着我们应该这样做。但是,如果这样做会使代码更有条理/更易于阅读,那么我们绝对应该这样做。
OOP非常有用的一个很好的实际例子是使用"产品"类和我在我们的网站上使用的对象。由于每个页面都是一个产品,并且每个产品都引用了其他产品,因此对于我们所引用的数据而言,它可能会非常混乱。这个" strURL"变量是指向当前页面,主页还是统计页面的链接吗?当然,我们可以使各种不同的变量引用相同的信息,但是proCurrentPage-> strURL易于理解(对于开发人员而言)。
此外,将功能添加到这些页面上会更加整洁。我可以做proCurrentPage-> CleanCache();随后是proDisplayItem-> RenderPromo();如果我只是调用这些函数并假设当前数据可用,谁知道会发生哪种恶魔。另外,如果我必须将正确的变量传递给这些函数,那么我又回到了为不同产品放置各种变量的问题。
相反,使用对象,我所有的产品数据和功能都很好,干净而且易于理解。
然而。 OOP的最大问题是当有人认为一切都应该是OOP时。这产生了很多问题。我的数据库中有88个表。我只有大约6个课,也许我应该大约有10个课。我绝对不需要88个课。在我使用它的情况下,大多数时候直接访问这些表是完全可以理解的,并且OOP实际上会使获取正在发生的事情的核心功能更加困难/乏味。
我认为,有用的对象和实用的过程的混合模型是最有效的编码方法。所有这些宗教战争中,人们主张使用一种方法却以牺牲其他方法为代价,这真是令人遗憾。他们俩都是好人,都有自己的位置。在大多数情况下,每个较大的项目中都同时使用这两种方法(在某些较小的项目中,可能只需要一个对象或者几个过程)。
回答
是的,OOP不能解决我们所有的问题,对此感到抱歉。但是,我们正在致力于解决所有这些问题的SOA。
回答
"现实世界不是" OO","
真的吗?我的世界充满了对象。我现在正在用一个。我认为让软件"对象"为真实对象建模可能不是一件坏事。
面向概念性事物(例如Windows,不是现实世界的窗口,而是计算机显示器上的显示面板)的OO设计经常有很多不足之处。但是对于诸如发票,运输单,保险索赔之类的现实世界而言,我认为这些现实世界都是物体。我的桌子上有一堆书,所以它们一定是真实的。
回答
I think those real world things are objects
你做?
发票有什么方法?等一下。它无法付款,无法发送,无法与供应商实际交付的商品进行比较。它根本没有任何方法。它完全是惰性的,没有功能。它是一种记录类型(如果需要,可以是一个结构),而不是对象。
同样,我们提到的其他内容。
仅仅因为某物是真实的,就不能使它成为OO这个词的对象。 OO对象是状态和行为的特殊耦合,可以自行起作用。这在现实世界中并不丰富。
回答
对我而言,OOP的价值在于缩小范围并将状态与行为分开。范围越小,代码越容易理解。
可以用大多数语言完成,实现此目标所需的一切是状态将方法调用委托给行为的一种方式,以及行为将调用进一步委托给父行为的一种方式。
要让一组类以有效的方式对领域建模,就没有魔术方法。就像钢琴一样,我们必须练习。 OOP是一种抽象工具,它可以以更简单的方式构建代码,但无法为我们考虑和分析应用程序的领域。
对我有用的是,尽可能长地靠近该域,同时仍然避免大多数代码重复。
回答
OOP非常适合对内部计算机结构进行编程,例如GUI"小部件",例如SelectList和TextBox可以是Item的子类型,它具有诸如" move"和" resize"之类的通用方法。
问题是,我们90%的人都在与发票,员工,工作,订单等业务概念一起工作的商业环境中工作。这些对象不适合OOP,因为"对象"更加模糊,可能会根据业务重组等情况进行更改。
最糟糕的情况是将OO狂热地应用于数据库,包括对SQL数据库的过分的OO"增强",除非数据库新手认为它们必须是正确的处理方式,因为它们是较新的,否则它们被正确地忽略了。
回答
我同意InSciTek Jeff。即使我们不是最纯粹地使用OO,封装理论也可以帮助降低潜在的结构复杂性:
http://www.edmundkirwan.com
@DrPizza
如果过程编程在相同程度上利用了封装的好处,那就太好了!
回答
OOP的目的是为程序员提供另一种方式来向机器和人员描述和传达代码问题的解决方案。其中最重要的部分是与人沟通。 OOP允许程序员通过以OO语言执行的规则来声明它们在代码中的含义。
与该主题的许多论证相反,OOP和OO概念遍及所有代码,包括使用非OOP语言(例如C)的代码。许多高级的非OO程序员甚至会使用非OO语言来近似对象的功能。
将OO内置到语言中只会给程序员提供另一种表达方式。
编写代码的最大部分不是与机器进行通信,这很容易,最大的部分是与人类程序员进行通信。
回答
在我所读过的唯一一个开发博客中,那个由Joel-On-Software-Found-of-SO所代表的家伙,很久以前我读到,OO不会导致生产率提高。自动内存管理。凉爽的。谁可以拒绝数据?
我仍然相信面向对象非面向对象的编程与面向函数的编程就是对内联编程的一切。
(而且我应该知道,就像我从GWBasic开始一样。)当我们重构代码以使用函数时," variable2654"将成为我们所使用方法的" variable3"。或者,更好的是,它有了一个我们可以理解的名称,如果函数很短,则称为"值",这对于完全理解就足够了。
当没有功能的代码变成带有方法的代码时,我们将删除大量的代码。
当我们将代码重构为真正的OO时,b,c,q和Z变为this,this,this和this。而且由于我不相信使用this
关键字,因此我们可以删除大量的代码。实际上,即使我们使用" this",我们也可以这样做。
我不认为OO是自然的隐喻。
我也不认为语言是自然的隐喻,我也不认为福勒的"气味"比说"这段代码的味道不好"更好。就是说,我认为OO并不是关于自然的隐喻,而认为对象只是突然出现在我们面前的人根本就没注意这一点。我们定义了对象Universe,更好的对象Universe会导致代码更短,更易于理解,更好地工作,或者所有这些(以及我遗忘的某些标准)。我认为使用客户/域的自然对象作为编程对象的人缺少重新定义Universe的能力。
例如,当我们使用航空公司预订系统时,所谓的预订可能根本不符合法律/商务预订。
一些基本概念是很酷的工具
我认为大多数人都夸大了"当我们有锤子时,他们都是钉子"的事情。我认为硬币/镜子的另一面也是如此:当我们拥有多态性/继承性之类的小工具时,我们会发现适合手套/袜子/隐形眼镜之类的用途。 OO的工具非常强大。我认为,单一继承是绝对不可让人迷失的必要,而我自己的多重继承软件则无法承受。
OOP的意义是什么?
我认为这是处理绝对大量代码库的好方法。我认为它可以让我们组织和重新组织代码,并提供一种语言来执行此操作(除了我们正在使用的编程语言之外),并以一种非常自然且易于理解的方式对代码进行模块化。
这是因为这是一个像人生一样令人大开眼界的过程:我们越来越多地从经验中了解OO,并开始避免某些模式,并在变得更聪明时采用其他模式。最好的例子之一是我们停止对不控制的类使用继承,而改用Facade模式。
OOP注定会被大多数开发人员误解
我确实想提到我们是对的。在大多数情况下,可重用性是一个白日梦。这是来自安德斯·赫伊尔斯贝格(Anders Hejilsberg)的引述,内容来自此处:
关于小文章/问题
这是将变量与与其交互的函数/方法/子例程组合在一起的唯一的语言便携式方法。
If you ask beginning programmers to write a calendar control, they often think to themselves, "Oh, I'm going to write the world's best calendar control! It's going to be polymorphic with respect to the kind of calendar. It will have displayers, and mungers, and this, that, and the other." They need to ship a calendar application in two months. They put all this infrastructure into place in the control, and then spend two days writing a crappy calendar application on top of it. They'll think, "In the next version of the application, I'm going to do so much more." Once they start thinking about how they're actually going to implement all of these other concretizations of their abstract design, however, it turns out that their design is completely wrong. And now they've painted themself into a corner, and they have to throw the whole thing out. I have seen that over and over. I'm a strong believer in being minimalistic. Unless you actually are going to solve the general problem, don't try and put in place a framework for solving a specific one, because you don't know what that framework should look like.
回答
对我来说,OOP语法本身具有很多价值。与尝试使用一堆不同的flat(或者" floating")函数来对相同数据执行相同操作相比,使用试图表示真实事物或者数据结构的对象通常要有用得多。具有良好OOP的事物具有一定的自然"流动性",这对于长期读取,写入和维护更有意义。
回答
发票实际上并不是具有功能的"对象",它可以执行自身功能,对象实例可以存在,只是对数据执行功能而不必知道实际存在的数据类型,这并不一定。可以成功调用函数" invoice.toJson()",而不必知道结果将是Json是什么类型的数据,无论它来自数据库,XML,CSV还是什至来自另一个JSON对象。使用过程函数,我们突然需要了解更多有关数据的信息,并最终获得诸如" xmlToJson()"," csvToJson()"," dbToJson()"之类的函数。如果我们更改了基础数据类型,将会非常头痛。
OOP的要点是通过将其抽象化来隐藏实际的实现。为了实现该目标,我们必须创建一个公共接口。为了在创建该公共接口并使工作保持干燥的同时简化工作,我们必须使用诸如抽象类,继承,多态和设计模式之类的概念。
因此,对我来说,OOP真正的首要目标是使将来的代码维护和更改变得更加容易。但是即使如此,如果正确地以程序代码无法做到的方式正确完成,它确实可以大大简化事情。它是否与代码中的"真实世界"编程不匹配并不重要,无论如何也不会与真实世界对象进行交互。 OOP只是使我的工作更轻松,更快捷的工具,因此我每天都可以这样做。
OOP有助于将接口与实现分开。我们无需使用该语言的OOP支持即可从OO设计中受益。
回答
OOP发挥了巨大作用的一个小例子:
UNIX虚拟文件系统(VFS)层使用函数指针表提供了统一的接口(打开/读取/写入),这与C ++虚拟表分派非常相似。
客户端使用同一组呼叫,而不管它们是在与本地文件系统,远程网络文件系统(NFS)还是(今天)伪造的文件系统(例如/ proc)交谈。
请参阅原始的Sun论文:Vnodes:Sun UNIX中的多种文件系统类型的体系结构
关于函数式编程,我们十年后会说同样的话吗?
回答
对于可读性,我不太关心重用。后者意味着代码更容易更改。在构建软件的过程中,仅此一项就值得黄金。
回答
OO是使程序可读的非常有效的方法。重用或者不重用。
OOP的问题在于它已被超卖。
回答
正如艾伦·凯(Alan Kay)最初设想的那样,它是替代以往拥有原始数据和全全局例程的做法的绝佳选择。
然后,一些管理顾问类型将其锁定并作为软件的救世主出售,随后像旅鼠一样的学术界和行业也随之下跌。
现在,在其他好的想法(例如函数式编程)被卖空之后,它们就像翻滚一样翻滚。
那我会做些什么呢?很多,我为此写了一本书。 (它已经绝版了,我一分钱也没收到,但我们仍然可以得到副本。)
我有建设性的回答是,不要将编程视为现实世界中事物建模的一种方式,而是将其编码为需求的一种方式。
这是非常不同的,并且基于信息论(任何人都可以理解的水平)。它说,可以将编程视为定义语言的过程,而这样做的技巧对于良好的编程至关重要。
它提升了特定领域语言(DSL)的概念。它完全同意DRY(请勿重复)。它极大地支持了代码生成。它导致软件的数据结构比现代应用程序中的典型数据要少得多。
它力求重新振兴前进的道路在于创造性的观念,甚至应该接受公认的观念。
现实世界不是" OO"。现实世界并不是由明智的事物构成的。相反,它是由混乱运动的粒子制成的。地球是颗粒汤。人们仍然看到鸟类,树木,天空,地面,森林,池塘。 OO是关于程序组件的抽象。考虑面向对象来建模除程序以外的其他东西从根本上是有缺陷的。
回答
所有的金钱和时间都不能使软件变得更好,因为它不能使程序员变得更聪明,也因为它不能改变人们对软件的看法。从我们使用的意义上来说," OOP"是一个流行语,用于从中获取收益
白痴。是的,把钱花在" OOP"教育和工具上的人是白痴。倾向于跌倒骗局的人往往是白痴。
" OOP"的值是同一程序内的抽象和代码重用。 OOP旨在与命令式程序一起使用。
如果我们从汇编例程起床。汇编是由标签和说明组成的成对的有序序列。汇编代码类似于"颗粒汤"。现在,我们可以转到子例程。子例程从该label:instruction -soup中选择一个标签,并将其余标签隐藏在该子例程中。随着效果代码变得更加抽象,命名空间变得更加整洁。
现在,如果我们考虑子例程的功能...几十年前,人们一直认为子例程在处理参数时处于最佳状态。这使他们可以为每个对象提供自己的协议。协议将包含label:procedure -pairs。现在称为选择器:方法-对。这些过程不再直接与其他过程绑定,解释了"后期绑定"术语。除了保留协议的历史记录(继承性)外,这还构成了小型对话中的"面向对象"。
我们已经失去了后期绑定机制的能力,并且忘记了继承的含义。而且我们还想知道那里缺少什么。 " OOP的价值在哪里?为什么所有的时间和金钱都无法使软件变得更好?"我想你把它们塞进了自己的屁股。当我们尝试进行结肠镜检查时,我们会发现它们。
首先,观察结果有些草率。我没有关于软件生产率的任何数据,也没有充分的理由相信它没有增长。此外,由于有很多人滥用OO,即使OO是自花生酱以来的最大成就,良好地使用OO并不一定会导致生产率提高。毕竟,一个无能的脑外科医生可能比没有一个更糟糕,但是有能力的人可能是无价的。
回答
话虽这么说,OO是一种不同的安排方式,将过程代码添加到数据上而不是使过程代码对数据进行操作。就其本身而言,这至少应该是一个小小的胜利,因为在某些情况下,面向对象的方法更自然。毕竟,没有什么可以阻止任何人使用C ++编写过程API,因此提供对象的选择反而使该语言更加通用。
此外,OO有一些功能非常出色:它允许旧代码无需更改就可以自动调用新代码。如果我有程序管理的代码,并且添加了与以前的代码相似但又不同的新事物,则必须更改程序代码。在OO系统中,我继承了功能,更改了所需内容,由于多态性,新代码自动被使用。这增加了变化的局限性,这是一件好事。
不利的一面是,好的OO不是免费的:需要时间和精力来正确学习它。由于这是一个主要的流行语,因此有很多人和产品都为做到这一点而做得不好。设计一个好的类接口要比一个好的过程API容易得多,并且存在各种容易犯的错误(例如深层的类层次结构)。
可以将其视为另一种工具,不一定总能更好。例如,除螺丝刀外还有锤子。也许我们最终会摆脱软件工程的实践,因为知道使用哪个扳手来敲入螺钉。
关于这已经有很多答案了,因为这是一篇旧文章,但我想我会提出建议。
回答
我们提到了"类分类法",这会涉及子类型化和多态性。所有这些都围绕着继承,在鼎盛时期被认为是OOP的灵丹妙药。如今,即使在进行大量OOP的商店中,也实际上不鼓励继承和大类层次结构。这是因为已发现OOP的其他原理,例如封装,松散耦合,内聚性等远比继承有用。我什至可以说松耦合是OO的原因,而不是代码重用的原因。代码重用通常发生在方法/功能级别。我有时会在不同的情况下重用类,但不是那么经常。松耦合虽然可以帮助组织很多系统。每个对象都有自己的作用域,除了访问器方法或者属性外,对象中的数据不应该或者不应该进行操作,每个对象应该做一件简单的事情,并且应该通过简单的接口与其他对象进行对话。这一少数原则有助于提高代码的可读性,帮助隔离错误并防止我们不得不在许多不同的地方进行很多更改来更改一件事情。当对象没有紧密缠绕在一起时,我们可以更改一个对象而不会影响其他对象。这对我来说是一个巨大的好处。继承仅在此后才有用。
代码重用仍然很重要,如果我们要复制,粘贴或者重写相同的代码,即使在普通的旧程序,结构化或者函数式编程下,这也是一个不好的做法。由于重复的工作,增加的维护和更多的错误,实际上增加了成本。
从1980年代中期在C / Unix(非OOP)中开始,然后在1990年转向C ++(OOP),然后在1996年左右进入Java(OOP)的经验,我发现OOP极大地提高了生产力,可维护性和健壮性与我之前从事的大型非OOP程序相比。
回答
我观察到的主要内容是,在非OOP应用程序中,我从事复杂性工作似乎相对于应用程序的复杂程度呈指数级增长,而在OOP应用程序中,我从事复杂性工作似乎具有更线性的关系相对于应用程序复杂程度的关系。
换句话说,对于设计良好的OOP应用程序,我们永远不会获得大型非OOP应用程序的" OMG该应用程序的源代码无法控制"的感觉。
作为OOP开发人员,我不能没有的其他事情就是编写代码的方式,该代码可以对应用程序问题域中存在的现实世界实体进行建模。对象以自己的方式生存,超越了任何结构(C)或者Records(Pascal)在糟糕的旧=]非OOP时代所做的工作。
一项规定是,OOP项目的首席架构师必须知道他在做什么,并且他通常必须花更多的思考时间来完成设计,而不是实际实施,但是"从头开始思考"的回报确实是惊人的。 。重用的机会或者超酷的设计优化机会暴露无遗,让我们在办公室里忙个不停并进行着陆工作……好吧,这对于办公室中的其他人可能看起来有些陌生,但是这种热情从未在办公室中发生过。面向对象的日子:)
我看过一些写得很差的OOP代码,也许正是我们所经历的,这可能导致我们提出问题。作为90年代中期的承包商,我经常发现" OO"设计已经由知道某类的人开始了,但仅此而已。这是一次非常痛苦的经历,我经常发现我在工作的头几个月涉及以完全不同的" OO"思维方式对团队进行教育。只有在每个人的大脑都重新连接好之后,我们大家才能组成一个团队继续前进,以创造出令人敬畏的东西。
许多人发现"大脑重新布线"过程太辛苦,痛苦或者太费力,因此将生命浪费在OOP上,所以我们会发现很多OO讨厌者,但我对此感到高兴,因为那是那些人这会让像我这样的人看起来不错:"什么,我们可以花$ X买到,它将在2个月内准备就绪,我们将为我们提供可维护的代码库!!!
{段落}