【问题标题】:Practical uses of OOPOOP 的实际使用
【发布时间】:2012-06-21 15:45:40
【问题描述】:

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

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

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

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

【问题讨论】:

  • 当我可以编程时,如果我必须学习新的东西,那有什么意义呢?小公司? -- 好吧,我想这意味着当他必须处理您的 OO 代码或反之亦然时会有一些摩擦。
  • 如果可以的话,我想为这个问题添加一个骑手,我最近已经进入 OOP。有没有人为 Ygam 同事的 cmets 辩护?听到利弊会很有趣。
  • 嗯...如果您的同事不了解 OOP 的优点,我不确定他是否应该“专业地”开发网站。我个人认为它不能解决所有问题,但它肯定会出现在任何超过 200 行的项目中。
  • 可能你的朋友一定看过这篇(假的??)采访:nsbasic.com/newton/info/nsbasic/interview.shtml

标签: oop paradigms


【解决方案1】:

我个人的看法:上下文

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

【讨论】:

  • 是的,完全正确。人类创造事物作为自然的模型。 OOP 更像现实生活; 事物是分开拍摄的。
  • 我同意。我的讲师在大学期间就是这样解释的。他说这有助于在现实世界(或接近)的事物上建模对象,因为现实世界中的对象不会发生太大变化,并且更容易在您的脑海中可视化。
  • 我认为 OOP 根本不像现实生活。我认为这是一种将现实生活简化和抽象为简单到足以让我们理解和操作的概念的尝试。想一想在 OOP 中准确地建模一件简单的事情,就像“一支笔在一张纸上写字”。
  • 这是一个支持 OOP 的经典论据,但我认为它并不能帮助顽固的 C 程序员理解适合 OOP 时的优势。我不会投反对票,但这是一个敏感的答案,真的没什么好说的。
  • @San Jacinto 我同意。捕获上下文的能力是 OOP 如此强大的部分原因,但简单地指出这一事实并不是支持 OOP 的有力论据。您需要具体的例子来说明在程序中添加上下文将如何节省您的时间、赚钱和美白牙齿。
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

  • 我同意将数据直接绑定到操作时语法更简洁,但对于不懂 OOP 的人来说,这只是语法糖。
  • 句法糖很有营养。我们在高级语言中所做的一切都是汇编程序之上的糖。每当我必须用汇编语言工作时,我就非常非常想念那颗糖。因此,我发现很难将任何提高生产力的语言结构视为“只是语法糖”。 IMO,任何不了解至少三种主要编程风格(命令式、函数式和 OOP)的软件开发人员都需要摆脱困境并认真学习。理解这些方法可以提供有效地分解任何语言或范式中的问题的关键概念。
【解决方案3】:

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

【讨论】:

  • 我同意,但我认为这无助于回答任何人关于 OOP 如何“更好”的问题。一个设计良好的 C 应用程序提供了同样的功能。 C 结构不是对象。 C++ 结构是一个对象。
  • Hmm.. 不是很明显,相反是真的,非 OO 设计没有这些好处,所以 OO 设计更好? C 结构与 C++ 结构一样是对象。事实上,如果 C++ 结构是您承认的对象,为什么不是 C 结构?
  • 面向对象或非面向对象设计具有这些特征的程度与设计人员的技能成正比。对于结构问题:在 C 中,我不能从另一个结构继承或变形为它。我无法在结构中嵌入功能逻辑并重载下一代所述结构中的行为。在 C++ 中,我可以做到这一切,因为 struct 键是创建类的门面。
  • 不要把我和不喜欢 OOP 的人混为一谈。它(几乎)是我使用的唯一范例。我只是发现这个问题的大部分论据都缺乏。
  • 所以这并不是说结构是不是对象,而是你的意思是让某个东西成为一个对象,它应该支持应该能够被覆盖的功能逻辑!我完全不同意,因为一个没有功能的对象仍然是一个对象,因为它拥有一组相关的项目。现在,即使您使用 struct 语法,您当然也可以将函数指针作为 struct 的数据成员来提供该功能。
【解决方案4】:

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

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

【讨论】:

  • 如果您扩展前两点并删除第三点,这个答案会好得多。
  • 我认为这个答案是另一个列出要点的答案(正如你所做的那样!)但没有说明为什么它“更好”。
【解决方案5】:

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

几个例子:

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

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

  • 看看 PostgresQL 是怎样的 实施方式与您的方式 数据库书说数据库应该 被实施,你会看到一个很大的 区别。本书会建议 每个运算符的节点对象。 Postgres 使用无数的表和 宏来尝试模拟这些节点。 它不那么漂亮,而且很多 因此更难扩展。

名单还在继续。

【讨论】:

  • 设计模式,尤其是那些被 GoF 书普及的模式,很大程度上是由于 C++ 和 Java 的局限性,特别是它们的静态特性而存在的。例如,策略模式被一流的程序消除了
  • 我不同意。我知道这是当今普遍的想法,但从历史上看是不准确的。大多数 GoF 模式起源于 Smalltalk,其中功能是一流的。确实,您可以采用第一类函数和闭包并获得与 OO 策略模式相同的许多好处,但这并不会使 OO 成为一个坏主意,就像 OO 使函数式编程成为一个坏主意一样。它们是同一想法的两种实现。
  • 更普遍的看法是 GoF 的设计模式在这些语言中“蒸发”了。 “过程调用模式”是我更喜欢引用的例子——在 algol 出现之前,你必须经历很多圈才能实现递归过程的概念。现在,在 C++ 中,过程调用模式很简单。我只写“foo(bar)”,然后神奇地保存了我的本地人,bar 被压入堆栈等。同样,工厂模式在 Python 中消失为“foo(bar)”,因为对象创建和函数调用是统一的.
【解决方案6】:

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

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

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

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

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

【讨论】:

    【解决方案7】:

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

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

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

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

    【讨论】:

      【解决方案8】:

      大约在 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 等静态类型语言中,建模现实世界往往需要曲折的抽象。通过观察成千上万的人努力为“形状”(形状、椭圆、圆形)的几何抽象等表面上简单的东西建模,您可以看到一个具体的例子,说明现实世界建模的难度。

      【讨论】:

        【解决方案9】:

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

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

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

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

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

        【讨论】:

        • 添加评论以说明您投反对票的原因通常被认为是礼貌的。
        • +1:封装和抽象一直存在。 IMO 多态性的概念是 OO 风格强大的唯一关键。
        【解决方案10】:

        请你的朋友想象他的房间、房子或城市中的任何对象......如果他能告诉一个这样的对象,它本身就是一个系统并且能够做一些有意义的工作.

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

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

        【讨论】:

          【解决方案11】:

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

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

          【讨论】:

            【解决方案12】:

            不仅如此

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

            您可以查找有关它的更多信息: - Java:休眠 - 点网:实体框架

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

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

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

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

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

            面向对象的方式

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

            类对象集合

            函数 ourFunctionForSaving() As String

            字符串_对象

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

            返回 _Objects 结束方法

            非OO方式

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

            现在让我们说

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

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

            让你的同事考虑一下 :)

            【讨论】:

              【解决方案13】:

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

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

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2013-12-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-02-21
                • 2011-10-01
                • 1970-01-01
                相关资源
                最近更新 更多