【问题标题】:Begin with OOP by using classes as a collection of methods? [closed]从 OOP 开始,使用类作为方法的集合? [关闭]
【发布时间】:2013-04-28 17:49:19
【问题描述】:

从面向对象的 PHP 开始,使用类作为方法的集合是否明智?这种方法有什么缺点吗?

我知道 OOP 远不止这些,但我的 PHP 项目太小,无法充分利用 OOP 所提供的一切。另一方面,我的项目变得太大,无法仅通过程序编程来更新/维护。

我读过很多关于 OOP 的主题,有时有人说“OOP 不仅仅是函数的集合”(或类似的东西)。这让我想到:这可能是真的,但这也可能是我通过这样做最终深入 OO 编程世界的机会。

那么,这是真正开始使用和学习 OOP 的明智的第一步吗?或者我需要了解哪些严重的缺点?

【问题讨论】:

  • 如果它可以帮助您编写更好的代码,为什么不呢?
  • 那不是面向对象的编程(根本不是),而是基于调用分类的编程。您可能想了解utility pattern 并查看Utility classes are evil? - 请记住,不同的编程语言有不同的需求。在 PHP 中,您应该了解静态和动态方法调用的不同。
  • 如果您想采用这种方法,只需获取good book on refactoring 并在途中应用您学到的知识。你最终会写出更好的代码。

标签: php oop


【解决方案1】:

由于这个问题实际上与 php 无关,而是与一般的 OOP 相关,所以这个答案应该对许多语言都有效。

OOP 中存在不同的模式。我建议阅读“四人帮”。这是一本非常好的书,它解释了一些在做 OOP 时可以使用的最基本的模式。

您应该考虑将所有函数存储在命名空间中,而不是使用类来保存一组静态函数。

类通常定义对象(如物理对象)。任何物理对象都有一组属性和行为。

在设计一个类时,您会尝试定义这些行为和属性。例如,一个包。

class Bag:
    // Methods
    function open: ...
    function close: ...
    function empty: ...
    function add(item): ...
    // Properties
    array items: []
    bool is_open: false

某些属性或方法可以对世界隐藏或可见。在我的示例中,每当您尝试清空或将对象添加到封闭的袋子时,您都可以让函数 add 抛出异常。很明显,这里的所有方法都与实际对象相关。

添加与包无关的方法或属性应属于不同的命名空间或类。这真的取决于你想要做什么。

【讨论】:

    【解决方案2】:

    有些东西是功能性的、程序性的并且基于一个对象。使用最适合情况的一种。你不会对这种哲学大错特错。

    【讨论】:

      【解决方案3】:

      免责声明:我有一段时间没有处理 php,所以我的语法可能是错误的。

      OOP 这个词在 imo 中有点模糊,意思是不同的人听到它时会想到略有不同的东西,所以当你听到矛盾的东西时不要感到困惑。

      使用类将相似的函数构建在一起不会损害您的代码,但是您基本上只是将类用作函数的命名空间。通常,您会希望以封装系统的某些方面的方式定义类,这意味着只有该类的代码必须直接处理该方面,而其他人只使用它类。

      例如,您可以有一个管理打印作业队列的类。如果您有一些想要打印文档的代码,它不必知道作业如何排队或在哪里排队或如何将它们发送到打印机,它只需要知道打印作业队列对象(我们称之为 @ 987654321@),可能有类似$jobQueue->enqueue($document)的方法。

      现在您可能会争辩说:“该代码也可以使用全局函数 enqueueJob($document)”,直到您想要拥有多个队列(用于不同的打印机)以及以不同方式工作的队列之前都是如此(将作业存储在数据库中,内存中,或者根本不存储 - 想象一个直接进入回收站的队列:))。使用 OOP,这种场景没有问题,并且这些细节对想要打印文档的代码完全隐藏 - 它所关心的是它有一个带有 enqueue 方法的作业队列对象。

      要获得这种作业队列的“可互换性”,他们需要有一个通用接口(在本例中为enqueue 方法),必须仔细选择该接口以满足代码的所有需求打印东西,但不对打印队列的工作方式做太多假设。例如,您可以想象enqueue 方法将文件路径作为参数,该参数告诉队列将其文件存储在哪里 - 但该接口对于在数据库上工作的队列将无用。这是找到好的抽象的艺术。

      现在回到您最初的问题,在我看来,只是将相关函数打包到一个类中并不是真正的 OOP,只要不考虑新类应该提供哪些抽象/接口。没有它,使用这个新类的所有代码都将被硬连线以使用它,并且如果您决定需要不同类型的打印机队列,则需要更改/重新检查。 :)

      但是,“not OOP”与“not a good idea”不同。我说去吧,重新安排你的职能。在我看来,重要的是要记住,并非所有事物都需要成为对象或适合某种抽象。但也许你会发现你确实有一些函数可以做类似的事情(文件中的队列,数据库中的队列),这些函数可以抽象为一个通用接口。

      【讨论】:

      • 非常感谢。您的回答不仅为我阐明了“抽象”和“接口”,而且还让我相信自己走在正确的道路上。
      【解决方案4】:

      您的问题确实很宽泛,但是当您继续进入面向对象分析和设计 (OOAD) 的世界时,它值得一个简单的答案,您可以记住并随身携带。

      那么,这是真正开始使用和学习 OOP 的明智的第一步吗?或者我需要了解哪些严重的缺点?

      您可以想象,我们不可能直接回答这个问题。什么聪明,什么不聪明,很大程度上取决于我们自己的能力。例如。对于某些人来说,它可能很聪明,因为它可以帮助他们及早停止错误,这是要走的路。对于其他人来说,这可能是一场彻底的灾难,因为他们没有发现任何错误,继续开发软件,因为他们认为:如果我没有发现错误,这是完全正确的。

      那么如何解决这个困境呢?很简单,我们在 OOP 中有两个部分,您可以轻松了解并随身携带。第一个称为 STUPID - 您可能会想象如果某样东西属于此类别意味着什么,第二个称为 SOLID 以及如何对待里面的东西也是自说自话。

      【讨论】:

      • 我的广泛问题值得一个“视情况而定”的答案。感谢您提供易于记忆的指南链接。
      【解决方案5】:

      我不建议,您会习惯于编写掩码为 OOP 的过程代码,这并不是您真正想要的。一开始可能很难,但是学习 OOP 的所有功能,阅读模式,强调编码标准,最重要的是,学习面向对象架构的应用程序。

      【讨论】:

        【解决方案6】:

        OOP 基本上只是一组方法。但是编程中的思维是不同的。在类中,您封装了类似的功能。代码更具可读性,您不需要一遍又一遍地编写相同的功能。它也更安全(私人成员),如果您正在编写库,最终用户只能更改您想要的内容等。 因此,我不建议尝试使用一组函数绕过 OOP 并改用真正的 OOP。没有理由不这样做。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-15
          • 1970-01-01
          • 2013-12-07
          • 1970-01-01
          • 1970-01-01
          • 2020-10-07
          • 2015-07-22
          • 2018-11-12
          相关资源
          最近更新 更多