OOP的实际用途

时间:2009-11-19 05:35:06

标签: oop paradigms

我最近与一位不是OOP粉丝的同事进行过辩论。引起我注意的是他说的话:

“在对象中进行编码有什么意义?如果它被重用,那么我可以创建一个库,并调用我手头所需的任何函数。我是否需要这些多态,继承,接口,模式的概念或者其他什么?“

我们是一家为电子商务网站和房地产开发小型项目的小公司。

如何在“日常,真实世界”的设置中利用OOP?或者OOP真的意味着解决复杂的问题,而不是用于“日常”开发吗?

13 个答案:

答案 0 :(得分:8)

我个人观点:背景

当您在OOP中编程时,您可以更好地了解上下文。它可以帮助您以更容易理解的方式组织代码,因为现实世界也是面向对象的。

答案 1 :(得分:7)

关于OOP的好处来自于将一组数据绑定到一组行为。

因此,如果您需要对相关数据集执行许多相关操作,您可以编写许多在结构上运行的函数,或者您可以使用对象。

对象以继承的形式为您提供一些代码重用帮助。

IME,使用一组具有已知属性和方法的对象更容易,它可以保留一组复杂的结构以及对它们起作用的函数。

有些人会继续谈论继承和多态性。这些都是有价值的,但OOP的真正价值(在我看来)来自它封装并将数据与行为相关联的好方法。

您应该在项目中使用OOP吗?这取决于您的语言支持OOP的程度。这取决于您需要解决的问题类型。

但是,如果你正在做小型网站,你仍然在谈论足够的复杂性,我会在开发语言中给予适当的支持,使用OOP设计。

答案 2 :(得分:6)

不仅仅是为了工作 - 朋友的观点,设计精良的OO设计更容易理解,遵循,扩展,扩展和实施。例如,委托明确相似的工作或保存应该保持在一起的数据(即使C结构是对象)也是如此。

答案 3 :(得分:5)

嗯,我相信很多人会给出更多学术上正确的答案,但这是我对一些最有价值的优势的看法:

  • OOP允许更好的封装
  • OOP允许程序员以更合乎逻辑的方式思考,使软件项目更容易设计和理解(如果设计得很好)
  • OOP节省时间。例如,看看你可以用C ++字符串对象,向量等做的事情。所有这些功能(以及更多)都是为了“免费”。现在,这些都是类库的特性而不是OOP本身,但几乎所有的OOP实现都带有很好的类库。你能用C(或大部分)实现所有这些东西吗?当然。但为什么要自己写呢?

答案 4 :(得分:3)

看看设计模式的使用,你会看到OOP的实用性。它不仅仅是封装和重用,还有可扩展性和可维护性。它是使事物变得强大的接口。

一些例子:

  • 实现不带对象的流(装饰器模式)很困难

  • 如果没有对象,将新操作添加到现有系统(例如新加密类型(策略模式))可能会很困难。

  • 看看PostgresQL的方式 与你的方式相对应 数据库书说数据库应该 实施,你会看到一个大的 区别。这本书会建议 每个运算符的节点对象。 Postgres使用无数表和 用于尝试模拟这些节点的宏。 它不那么漂亮和多了 因此而难以延伸。

列表继续。

答案 5 :(得分:3)

大多数编程语言的强大之处在于它们提供的抽象概念。面向对象编程提供了一个非常强大的抽象系统,它允许您管理相关想法或操作之间的关系。

考虑计算任意和不断扩展的形状集合的区域的任务。任何程序员都可以快速编写圆形,正方形,三角形等区域的函数。并将它们存储在库中。当试图编写识别和计算任意形状区域的程序时,困难就出现了。每次添加一种新形状(比如五边形)时,您都需要更新和扩展类似IFCASE结构的内容,以允许程序识别新形状并调用正确的区域来自“功能库”的例程。过了一段时间,与这种方法相关的维护成本开始堆积起来。

使用面向对象的编程,其中很多都是免费的 - 只需定义一个包含区域方法的Shape类。然后,在运行时处理的具体形状并不重要,只需将每个几何图形作为继承自Shape的对象并调用area方法即可。面向对象的范例处理是否在此时刻,使用此用户输入,我们是否需要计算半分钟前刚刚添加的圆形,三角形,正方形,五边形或椭圆形选项的区域。 / p>

如果您决定更改区域功能调用方式后面的界面怎么办?使用面向对象编程,您只需更新Shape类,并且更改会自动传播到从该类继承的所有实体。使用非面向对象系统,您将面临着通过“功能库”并更新每个单独界面的任务。

总之,面向对象编程提供了一种强大的抽象形式,可以通过消除代码中的重复并简化扩展和维护来节省您的时间和精力。

答案 6 :(得分:2)

所有编程范例都有相同的目标:隐藏不必要的复杂性。

一些问题可以通过命令式范例轻松解决,就像你的朋友一样。使用面向对象的范例可以轻松解决其他问题。还有很多其他paradigms。主要的(逻辑编程,函数编程和命令式编程)都是相同的;面向对象编程通常被认为是命令式编程的扩展。

当程序员对相似但不相同的项进行建模时,最好使用面向对象的编程。命令式范式将把不同类型的模型放在一个函数中。面向对象的范例将不同类型的模型分离为相关对象的不同方法。

你的同事似乎陷入了一种范式。祝好运。

答案 7 :(得分:2)

1994年左右,我试图同时理解OOP和C ++,并发现自己很沮丧,尽管我原则上能理解OOP的价值。我曾经习惯于从其他语言(主要是Basic,Assembly和Pascal家族语言)中弄乱应用程序的任何部分的状态,似乎我放弃了生产力,支持一些学术抽象。不幸的是,我与MFC这样的OO框架的第一次遭遇使得它更容易入侵,但并不一定提供很多启蒙。

只有通过持久性,暴露于交替(非C ++)处理对象的方式,以及仔细分析1)工作的OO代码和2)比等效的程序代码更加连贯和直观地阅读我开始真的明白了。 15年后,我经常对新的(对我来说)发现一些聪明但却令人印象深刻的简单OO解决方案感到惊讶,我无法想象这些解决方案在程序方法上做得很好。

在过去的几年里,我一直在尝试理解函数式编程范例。用保罗格雷厄姆的话说,当你向下看动力连续体时,你会看到所有缺失的东西。当你查看动力连续体时,你看不到力量,你只是看到了怪异。

我认为,为了承诺以不同的方式做某事,你必须1)看到一个人显然更有效率,更强大的结构和2)当你发现自己撞墙时暂停怀疑。在他们对新范式的理解方面,至少还有一点导师可能会有所帮助。

除非要求暂停怀疑,否则如果你想让某人快速了解OO模型的价值,我认为你可以做得比在Rails上花一周时间与实用程序员一起预订更糟糕。不幸的是,它确实遗漏了魔法如何运作的许多细节,但它是对OO抽象系统的强大功能的一个很好的介绍。如果在完成那本书之后,你的同事由于某种原因仍然没有看到OO的价值,那么他/她可能是一个绝望的案例。但是,如果他们愿意花一点时间使用一种具有强烈自以为是的OO设计的方法,并且比用程序语言做同样的事情要快0-60,那么可能只会有希望。即使你的工作不涉及网络开发,我认为这也是正确的。

我不太确定提出“真实世界”会成为编写优秀应用程序的工作框架的卖点,因为事实证明,特别是在C#和Java等静态类型语言中,建模现实世界经常需要曲折的抽象。你可以看到一个具体的例子,说明现实世界建模的难度,看看成千上万的人在努力建模,就像“形状”(形状,椭圆,圆形)的几何抽象一样简单。

答案 8 :(得分:2)

对我而言,在你开始讨论继承和多态之前,OOP的力量并没有显现出来。

如果一个人对OOP的论证依赖于封装和抽象的概念,那对我来说这不是一个非常有说服力的论据。我可以编写一个巨大的库,只记录我希望用户注意的接口,或者我可以依赖语言级构造,比如Ada中的包,使字段成为私有,只显示我想要的内容露出。

然而,当我在通用层次结构中编写代码以便以后可以重复使用时,真正的优势就来了,这样就可以使用相同的精确代码接口来实现相同的结果。

为什么这个方便?因为我可以站在巨人的肩膀上完成我目前的任务。我的想法是,我可以将问题的各个部分归结为最基本的部分,构成组成对象的对象......组成项目的对象。通过使用在一般情况下非常好地定义行为的类,我可以使用相同的经过验证的代码来构建同一事物的更具体版本,然后是同一事物的更具体版本,然后更具体同一件事的版本。关键是这些实体中的每一个都具有已经编码和测试的共性,并且不需要在以后再次重新实现它。如果我不使用继承,我最终会重新实现常用功能或显式链接我的新代码与旧代码,这为我提供了引入控制流错误的场景。

在我需要从对象获得某种功能的情况下,多态性非常方便,但同样的功能也需要来自类似但独特的类型。例如,在Qt中,可以将项目插入到模型中,以便可以显示数据,并且可以轻松维护该对象的元数据。如果没有多态性,我需要为自己提供比现在更多的细节(I.E.我需要实现相同的代码接口,这些接口执行与原本打算在模型上使用的项目相同的业务逻辑)。因为我的数据绑定对象的基类本身与模型交互,所以我可以毫无困难地将元数据插入到该模型中。我从对象中得到了我需要的东西,而不用担心模型需要什么,模型得到它需要的东西,而不用担心我已经添加到类中。

答案 9 :(得分:1)

让你的朋友在他的房间,房子或城市中可视化任何对象......如果他能告诉单个这样的对象哪个系统本身并且能够做一些有意义的工作。

像按钮这样的东西不是单独做某事 - 需要很多物品来打电话。同样,汽车发动机由曲轴,活塞,火花塞组成。 OOPS概念已经从我们对自然过程或生活中的事物的感知演变而来。

“内部COM”一书讲述了COM的目的,即通过提问来识别动物的童年游戏中的类比。

答案 10 :(得分:0)

设计胜过技术和方法。好的设计往往包含复杂性管理的普遍原则,例如demeter定律,这是OO语言特征努力编纂的核心。

良好的设计不依赖于OO特定语言功能的使用,尽管使用它们通常是最有利的。

答案 11 :(得分:0)

不仅是

  • 在当前情况下为其他人(和您自己)编程更容易/更易于维护
  • 它已经允许更简单的数据库CRUD(创建,更新,删除)操作。

您可以找到有关它的更多信息: - Java:Hibernate - Dot Net:实体框架

了解LINQ(Visual Studio)如何让您的编程生活更轻松。

  • 此外,您可以开始使用设计模式来解决现实生活中的问题(设计模式都是关于OO的)

用一个小小的演示演示可能会很有趣:

  • 假设您需要以类似的方式将员工,帐户,成员,书籍存储在文本文件中。

.PS。我尝试用PSEUDO方式编写它:)

OO方式

您致电的代码: io.file.save(objectsCollection.ourFunctionForSaving())

class objectsCollection

函数ourFunctionForSaving()As String

String _Objects

   for each _Object in objectsCollection
         Objects &= _Object & "-"
   end for

返回_Objects 结束方法

NON-OO Way

我认为我不会记下非oo代码。但想一想:)

现在让我们说'

以OO方式。上面的类是保存书籍,员工,成员,帐户,...的所有方法的父类。 如果我们想要更改保存到文本文件的方式会发生什么?例如,使其与当前标准(.CVS)兼容。

让我们说我们想添加一个加载函数,你需要编写多少代码? 在OO-方式中,您只需要添加一个New Sub方法,该方法可以将所有数据拆分为参数(这只发生一次)。

让你的同事考虑一下:)

答案 12 :(得分:0)

在状态和行为不一致的域中,面向对象降低了这些域中的总体依赖性密度(即复杂性),这使得生成的系统不那么脆弱。

这是因为面向对象的本质是基于这样一个事实,即在组织上,它根本不会在状态和行为之间消除风险,将两者统一视为“特征”。对象只是一组功能,可以最大限度地减少整体依赖。

在其他领域,面向对象不是最好的方法。对于不同的问题,存在不同的语言范例。有经验的开发人员知道这一点,并愿意使用最接近域的任何语言。