10

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

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

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

如何在“日常、现实世界”设置中利用 OOP?还是 OOP 真的是为了解决复杂的问题而不是为了“日常”开发?

4

13 回答 13

9

我个人的看法:上下文

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

于 2009-11-19T05:46:10.360 回答
8

OOP 的好处在于将一组数据与一组行为联系起来。

所以,如果你需要对一组相关的数据做很多相关的操作,你可以写很多对一个结构体进行操作的函数,或者你可以使用一个对象。

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

在 IME 中,使用具有一组已知属性和方法的对象更容易使用它来保留一组复杂的结构和对其进行操作的函数。

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

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

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

于 2009-11-19T05:50:34.103 回答
6

不仅仅是让某些东西正常工作——你朋友的观点,一个设计良好的 OO 设计更容易理解、遵循、扩展、扩展和实施。例如,委派绝对相似的工作或保存应该保持在一起的数据(是的,甚至 C 结构也是一个对象)要容易得多。

于 2009-11-19T05:40:45.840 回答
5

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

  • OOP 允许更好的封装
  • OOP 允许程序员以更合乎逻辑的术语进行思考,使软件项目更易于设计和理解(如果设计良好)
  • OOP 可以节省时间。例如,看看您可以使用 C++ 字符串对象、向量等执行的操作。所有这些功能(以及更多功能)都是“免费”提供的。现在,这些确实是类库的特性,而不是 OOP 本身,但几乎所有 OOP 实现都带有不错的类库。你能用C(或大部分)实现所有这些东西吗?当然。但是为什么要自己写呢?
于 2009-11-19T05:45:30.900 回答
3

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

几个例子:

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

  • 在没有对象的情况下,向现有系统添加新操作(例如新的加密类型(策略模式))可能很困难。

  • 看看 PostgresQL 的实现方式与你的数据库书籍所说的数据库应该实现的方式,你会发现很大的不同。本书将为每个算子推荐节点对象。Postgres 使用无数的表和宏来尝试模拟这些节点。因此,它不那么漂亮,也更难扩展。

名单还在继续。

于 2009-11-19T05:53:45.103 回答
3

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

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

使用面向对象的编程,很多这些都是免费的——只需定义一个包含 area 方法的 Shape 类。然后,在运行时处理什么特定形状并不重要,只需将每个几何图形都设为继承自 Shape 的对象并调用 area 方法即可。面向对象范式处理此时是否需要通过用户输入计算圆形、三角形、正方形、五边形或半分钟前刚刚添加的椭圆选项的面积的细节。

如果您决定更改调用 area 函数的方式背后的接口怎么办?使用面向对象编程,您只需更新 Shape 类,更改就会自动传播到从该类继承的所有实体。对于非面向对象的系统,您将面临通过“函数库”和更新每个单独界面的任务。

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

于 2009-11-19T08:01:41.897 回答
2

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

有些问题很容易通过命令式范式解决,就像你朋友使用的那样。其他问题很容易用面向对象的范式解决。还有许多其他范式。主要的(逻辑编程、函数式编程和命令式编程)都是等价的;面向对象编程通常被认为是命令式编程的扩展。

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

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

于 2009-11-19T07:08:55.397 回答
2

大约在 1994 年,我试图同时理解 OOP 和 C++,结果发现自己很沮丧,尽管我原则上可以理解 OOP 的价值是什么。我已经习惯于从其他语言(主要是 Basic、Assembly 和 Pascal 系列语言)中弄乱应用程序任何部分的状态,以至于我似乎放弃了生产力来支持一些学术抽象。不幸的是,我最初几次接触像 MFC 这样的 OO 框架使得它更容易被破解,但并没有提供太多的启发。

只有通过持久性、接触处理对象的替代(非 C++)方式以及仔细分析 OO 代码的组合,1)工作和 2)比我开始的等效程序代码更连贯和直观地阅读真正得到它。15 年后,我经常对(对我而言)聪明的新发现感到惊讶,但令人印象深刻的简单 OO 解决方案,我无法想象在程序方法中如此巧妙地做到这一点。

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

我认为,为了承诺以不同的方式做某事,你必须 1) 看到某人使用更强大的构造显然更有效率,以及 2) 当你发现自己碰壁时暂停怀疑。拥有一位对新范式的理解也至少稍微深入一点的导师可能会有所帮助。

除非有暂停怀疑所需的进取心,否则如果您希望某人快速了解 OO 模型的价值,我认为您可以做的比请某人花一周时间阅读有关 Rails 的实用程序员书要糟糕得多。不幸的是,它确实遗漏了很多关于魔法如何工作的细节,但它很好地介绍了 OO 抽象系统的强大功能。如果你的同事在读完那本书后,由于某种原因仍然看不到 OO 的价值,那么他/她可能是一个绝望的案例。但是,如果他们愿意花一点时间来使用一种方法,这种方法具有强烈的自以为是的 OO 设计,并且比用过程语言做同样的事情要快得多,而且从 0 到 60 的速度要快得多,那么可能就有希望了。我认为即使您的工作不涉及 Web 开发也是如此。

我不太确定提出“现实世界”是否会像编写优秀应用程序的工作框架一样成为卖点,因为事实证明,尤其是在 C# 和 Java 等静态类型语言中,对现实世界进行建模通常需要曲折的抽象。通过观察成千上万的人努力为像“形状”(形状、椭圆、圆形)的几何抽象这样表面上简单的东西建模,您可以看到一个具体的例子,说明现实世界建模的难度。

于 2009-11-19T07:52:39.973 回答
2

对我来说,直到您开始谈论继承和多态性,OOP 的力量才会显现出来。

如果一个人支持 OOP 的论点在于封装和抽象的概念,那么这对我来说并不是一个非常有说服力的论点。我可以编写一个庞大的库,只记录我希望用户知道的接口,或者我可以依赖语言级别的结构(如 Ada 中的包)将字段设为私有,只公开我想要的内容暴露。

然而,真正的优势在于,当我在通用层次结构中编写代码以便以后可以重用它,以便将相同的确切代码接口用于不同的功能以实现相同的结果时。

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

多态性在我需要从对象实现特定功能的情况下非常方便,但类似但独特的类型也需要相同的功能。例如,在 Qt 中,有将项目插入模型的想法,以便可以显示数据并且您可以轻松地维护该对象的元数据。如果没有多态性,我将需要比目前更多的细节来困扰自己(即,我需要实现与最初打算在模型上运行的项目执行相同业务逻辑的相同代码接口)。因为我的数据绑定对象的基类与模型进行本机交互,所以我可以将元数据插入到这个模型中,而不会有任何麻烦。我从对象中得到我需要的东西,而不用关心模型需要什么,

于 2009-11-20T03:17:16.800 回答
1

让你的朋友想象他的房间、房子或城市中的任何物体……以及他是否能分辨出一个这样的物体本身是一个系统并且能够做一些有意义的工作。

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

《Inside COM》一书通过提出问题来识别动物的童年游戏类比,讲述了 COM 的目的。

于 2009-11-19T09:49:32.243 回答
0

设计胜过技术和方法。好的设计倾向于包含复杂性管理的通用原则,例如分度法则,这是 OO 语言特性努力编码的核心。

好的设计不依赖于使用面向对象的特定语言特性,尽管使用它们通常符合人们的最佳利益。

于 2009-11-19T07:12:24.790 回答
0

它不仅使

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

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

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

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

也许用一个小演示来演示甚至很有趣:

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

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

OO方式

您调用的代码:io.file.save(objectsCollection.ourFunctionForSaving())

类对象集合

函数 ourFunctionForSaving() 作为字符串

字符串_对象

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

return _Objects 结束方法

非OO方式

我不认为我会写下非 oo 代码。但是想想看:)

现在让我们说

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

假设我们要添加一个加载功能,您需要编写多少代码?在 OO 方式中,您只需要添加一个 New Sub 方法,该方法可以将所有数据拆分为参数(这种情况发生一次)。

让你的同事考虑一下:)

于 2009-11-19T07:30:10.203 回答
0

在状态和行为不一致的领域中,面向对象降低了这些领域内的整体依赖密度(即复杂性),从而使最终的系统不那么脆弱。

这是因为面向对象的本质是基于这样一个事实,即在组织上,它根本不区分状态和行为,将两者统一视为“特征”。对象只是为了最小化整体依赖性而聚集在一起的特征集。

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

于 2009-11-20T02:33:22.977 回答