【问题标题】:Why use PHP OOP over basic functions and when?为什么在基本功能上使用 PHP OOP?何时使用?
【发布时间】:2010-10-17 12:21:49
【问题描述】:

关于这个问题有一些帖子,但我没有清楚地知道何时使用面向对象编码以及何时在包含中使用编程函数。也有人跟我提过,OOP 运行起来非常繁重,而且工作量更大。是这样吗?

假设我有一个包含 50 个函数的大文件。为什么我要在课堂上调用这些?而不是通过function_name()?我应该切换并创建一个包含我所有功能的对象吗?有什么优势或具体区别?它给 PHP 中的 OOP 代码带来什么好处?模块化?

【问题讨论】:

  • 我前段时间写了一篇博文,可能会帮助您了解其中的区别:Procedural vs. OOP Explained
  • VirtuosiMedia,死链接...?

标签: php oop


【解决方案1】:

在很多情况下,过程式编程就可以了。为了使用它而使用 OO 是没有用的,特别是如果你最终会得到 POD 对象(plain-old-data)。

OO 的强大主要来自于继承和多态。如果您使用类,但从不使用这两个概念中的任何一个,那么您可能一开始就不需要使用类。

OO 最出色的地方之一是 IMO,它允许您摆脱开机类型代码。考虑:

function drive($the_car){

    switch($the_car){

      case 'ferrari':
          $all_cars->run_ferrari_code();
          break;

      case 'mazerati':
          $all_cars->run_mazerati_code();
          break;

      case 'bentley':
          $all_cars->run_bentley_code();
          break;
    }
}

使用它的 OO 替代方案:

function drive($the_car){

    $the_car->drive();
}

多态性将允许根据运行时信息发生正确类型的“驱动”。


关于多态性的说明:

这里的第二个示例有一些前提:即所有汽车类都将扩展 abstract 类或实现 interface

两者都允许您强制扩展或实现类以定义特定功能,例如drive()。这非常强大,因为它可以让您drive() 所有汽车,而无需知道您正在驾驶哪一辆;那是因为他们正在扩展一个包含drive() 方法的抽象类或实现一个强制定义drive() 方法的接口。

只要您确保所有特定汽车要么扩展抽象类car,要么实现canBeDriven 之类的接口(两者都必须声明drive() 方法) 你可以在你知道是汽车(但不是什么类型的汽车)的对象上调用 drive() 方法,而不用担心它没有被定义,因为 PHP 会向你抛出致命错误,直到你在你的特定的汽车类别。

【讨论】:

  • 不太了解您的替代示例。
  • 如果您使用正确的 OOP,那么 $the_car 可能指向任何类型的汽车。因为所有不同类型的汽车都有一个 drive() 方法,所以无论汽车类型如何,您都可以安全地调用它。在运行时,它知道它是什么类型的汽车,并自动调用正确的汽车。
  • 只是遇到这个,也没有得到替代示例。您只是将一个对象传递给一个函数并调用 drive()。猜测您在实例化期间定义了对象但未显示?这作为 OOP 示例更有意义 $car_object = new carClass("$the_car");然后只需运行 $car_object->drive();
  • 我认为编写没有对象的函数更容易更短,你可以将类名放在函数名中,例如sec_do_check() sec_redirect_home() 等比 $ObjSecurity->redirect_home() 短得多;对于上面的示例很好的示例,但是如果没有 oop,它可以做得更短,而无需直接包装 function run($car_type) {...} 换句话说,您不需要针对不同汽车的不同功能,它完全是假的示例。除非您指定驱动器在做什么。即使你这样做,我也可以在没有 oop 的情况下写得更短。
【解决方案2】:

我会尽量保留我的答案作为补充,因为 Majd Taby 和 Coobird 的答案非常好。

多年来,我主要是一名程序程序员,并没有与 OOP 编程作斗争,但从未真正看到太多相关性……直到我开始在团队中工作并构建更重要和更复杂的项目。

在我看来,当您需要为更复杂的应用程序编写精简、易于维护的代码时,OOP 真的很出色。请注意,并非在所有情况下都如此,但在某些情况下,程序就不能很好地发挥作用。

我的大部分优秀 OOP 实现示例都针对我有几件相关但略有不同的项目的项目。具有大量表单、大量用户、大量产品等的网站。

它们都有类似的行为名称,如 print()、update() 等...但是通过将它们封装为对象并在类中改变方法的实现,我可以使我的代码在运行时非常简单和干净地点。此外,这一点很关键,尽管有不同的行为,但我可以使用不同的对象在整个应用程序中使用相同的方法调用。它允许第二个开发人员在我处理更深层次的代码时进行实际实现。

我不知道这是否有帮助,但作为不久前处于你这种情况的人来说,我喜欢 OOP。

【讨论】:

    【解决方案3】:

    在程序中使用面向对象的编程方法而不是过程式编程方法实际上并不取决于语言(不管是不是 PHP),而是取决于您要解决的问题的类型。

    (我只是在示例中使用伪代码,因为我对 PHP 不太熟悉。)

    例如,如果您有一个程序,您只是按顺序执行一堆功能,那么程序就可以了。例如,如果它是一个简单的字符串操作程序,那么程序方法就足够了:

    perform_truncation(my_string, 10)
    to_upper(my_string)
    perform_magic(my_string, hat, rabbit)
    

    但是,如果您要处理许多不同的项目(例如文件,或者对象的任何其他表示形式),那么面向对象的方法会更好。

    例如,如果您有一堆 Cars 并希望他们发送到 drive,那么在程序上,您可以执行以下操作:

    drive_car(first_car)
    drive_car(second_car)
    

    在 OOP 中,Car 可以自行驱动:

    RedCar myRedCar();
    BlueCar myBlueCar();
    
    myRedCar.drive();
    myBlueCar.drive();
    

    而且,由于每辆车都是不同的类别,它们的行为可以有不同的定义。此外,它们可能都是子类或Car,它们可能具有共同的功能。

    这真的归结为问题的类型,这使得任何一种程序方法都比面向对象更好,反之亦然。

    抛开程序化或面向对象的问题不谈,一个源文件有很多功能可能是一种“代码味道”。这也适用于包含许多功能的类,这些功能可以作为单独类中的单独功能更好地执行。

    这里的问题可能是代码组织而不是决定选择过程或面向对象的编程。这里可能需要将函数组织到单独的源文件中,而不是放弃编写程序的过程方法。

    毕竟,有很多程序是用过程式编程方法编写的,写得好,易于维护。

    【讨论】:

      【解决方案4】:

      假设我有一个包含 50 个文件的大文件 函数,我为什么要调用 这些在一个班?而不是通过 函数名()。我应该切换和 创建包含我所有的对象 函数?

      迁移到 OOP 不应被视为上述方式中的简单“切换”。

      OOP 需要一种完全不同的编程思维方式,这涉及重新连接大脑。由于大脑的重新布线不会在一夜之间发生,因此许多人不愿意将自己暴露在所需的重新布线过程中。不幸的是,重新布线将花费时间和精力:研究、教程、反复试验。

      这确实涉及退后一步并了解 OOP 背后的概念,但作为在 www 之前经历过此过程的人来说,回报将是非常值得的。

      在您“了解”并在日常生活中遵循 OOP 最佳实践后,您将告诉其他人您的编程生活如何变得更好。

      一旦你真正理解了 OOP,你就会回答你自己的问题。

      【讨论】:

      • OOP 只是编写 MVC 的一种方法,不要使用 oop,被认为是更好的方法
      【解决方案5】:

      如果你在 Utilities 类中有 50 个函数而不是 50 个静态方法,你会“污染”全局命名空间。

      使用具有 50 个静态方法的类,方法名称是类的本地方法。

      【讨论】:

      • 同意!但 Codex 并未提及他使用的是哪个版本。就个人而言,我仍然使用 5.2.6
      • 这不是支持实际的面向对象编程的论据,这就是这个问题的意义所在;相反,这与使用类来命名其他免费方法的常用模式有关。
      • 没有理由你不能对你的函数名稍微小心一点。
      【解决方案6】:

      我不能说哪个更好。但根据我的经验,您可以使用 OOP 进行更好的代码管理。你知道哪个代码在哪里,在哪个文件中定义了什么功能等等。 关于 OOP 的运行时开销,我在某处读到(我认为这是真的),如果您在经典函数中编写了错误的代码,并且在 OOP 中编写了相同的错误代码,则函数版本会更好地工作。因此,如果您的代码写得不错,则没有证据表明 OOP 会使您的应用程序运行缓慢。还要记住,这些“慢”和“开销”的东西都以毫秒为单位。因此,如果您的应用程序没有为大量用户提供服务(例如一分钟内超过 100 个用户),您可能不会感觉到任何差异。

      【讨论】:

        【解决方案7】:

        OOP 允许您创建结构化的代码容器,称为类,它们可以是彼此的父/子。这有助于构建应用程序,因为它更易于维护,并且如果操作得当,可以减少代码冗余。 OOP 确实增加了一些开销,但它并不明显,并且被程序代码的不可维护性所抵消。如果您要编写一个大型应用程序,请务必使用 OO,尤其是当它要由很多人开发时。

        例如,假设您正在设计一个简单的网站。您可以创建一个 Page 对象。页面对象负责访问数据库并获取页面的各种设置,例如元数据、标题标签,甚至页面上某些“组件”的数量及其类型(例如日历控件、小部件等)。

        然后,您可以创建另一个扩展 Page 的类,例如 Index。索引将是索引或主页。如果您有产品目录,则可以有目录类扩展页面。由于您的目录部分和主页都需要从数据库中获取有关页面元数据和页面基本结构的数据,因此拥有 1 个已经为您执行此操作的对象会有所帮助。在这两种情况下,页面都会完成所有工作并从数据库中获取页面数据,将其加载到变量中,然后在您的索引类和目录类中都可以访问这些变量。您不必编写代码即可进入数据库并在您编写的每个页面中再次获取它。

        现在还有其他方法可以在程序上执行此操作,例如使用包含。但是,您会发现自己犯的错误和错误更少。例如,您可以在 Page 类中定义一个抽象方法。这意味着这个方法必须在任何扩展它的对象中定义。因此,假设您在 Page 类中创建了一个 setPageAttributes() 函数作为抽象函数。当你这样做时,你会创建一个空函数。当您创建索引类时,您必须创建一个 setPageAttributes() 函数(用于填充它,例如访问 Page 类中定义的变量并使用它来设置页面、模板或查看您正在使用的视图)或您收到 PHP 错误。

        如果您正在与其他人一起编写您的项目,抽象方法会告诉该人,“嘿,您需要在您编写的任何代码中定义这些函数”。这迫使应用程序保持一致。

        最后,如果你不做 OOP,你就不能去诸如 MVC 格式之类的框架。虽然没有必要使用 MVC,并且存在一些争论,但它确实分离了应用程序的所有组件,并且在许多人(设计师、编码人员、营销人员)在同一代码上工作的环境中是必要的。

        【讨论】:

          【解决方案8】:

          使用 oop 可以为您带来以下好处:

          1. 结构化
          2. 可重用性
          3. 易于维护
          4. 数据封装

          到了制作具有 50 个函数的大文件的地步。你可以这样做,但是当涉及到函数的流程以及如何在每个函数之间绑定数据数据时,将是一个最大的问题。

          另外,如果您想替换最大的流程块,那么对于未来的维护,相信我,您必须访问每个功能并围绕它进行调整。此外,您永远不知道您的函数在代码的其他部分中是如何使用的。所以面向对象编程总是可取的。

          【讨论】:

            【解决方案9】:

            接受的答案似乎忽略了声明可以根据变量名称调用函数,例如下面的示例:

            function drive($the_car){
                $the_car();
            }
            

            诚然,在这种情况下,每辆车都需要一个函数,但它比建议的 switch 语句更有效。


            可以很容易地提供其他变量:

            function operate($the_car,$action){
                $the_car($action);
            }
            
            function ferrari($action){
                switch($action){
                    case 'drive':
                        echo 'Driving';
                        break;
            
                    case 'stop':
                        echo 'Stopped';
                        break;
            
                    default: return;
                }
            }
            
            
            operate('ferrari','drive');
            

            这里有一个 switch 语句,但它提供了原始示例中没有的附加功能,所以这绝不是矛盾的。

            【讨论】:

              【解决方案10】:

              PHP 中使用了 OOPs 概念,以保护代码安全。由于所有查询都写在函数文件而不是代码文件中,所以没有人可以轻易破解我们的代码。所以最好在 PHP 中使用类而不是直接编写查询。

              【讨论】:

                猜你喜欢
                • 2016-10-08
                • 1970-01-01
                • 1970-01-01
                • 2012-02-22
                • 1970-01-01
                • 2011-09-23
                • 1970-01-01
                • 2017-07-06
                • 1970-01-01
                相关资源
                最近更新 更多