design-patterns - 在 PHP 项目中,存在哪些模式来存储、访问和组织辅助对象?

标签 design-patterns oop php

就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the help center为指导。




10 年前关闭。










锁定。这个问题及其答案是locked因为这个问题是题外话,但具有历史意义。它目前不接受新的答案或互动。








在基于 PHP 的面向对象的项目中,您如何组织和管理您的助手对象,例如数据库引擎、用户通知、错误处理等?

假设我有一个大型 PHP CMS。
CMS 分为不同的类。几个例子:

  • 数据库对象
  • 用户管理
  • 用于创建/修改/删除项目的 API
  • 向最终用户显示消息的消息传递对象
  • 带您到正确页面的上下文处理程序
  • 显示按钮的导航栏类
  • 日志对象
  • 可能,自定义错误处理

  • 等等。

    我正在处理一个永恒的问题,即如何最好地使需要它的系统的每个部分都可以访问这些对象。

    许多年前,我的第一个方法是拥有一个 $application global ,其中包含这些类的初始化实例。
    global $application;
    $application->messageHandler->addMessage("Item successfully inserted");
    

    然后我改用单例模式和工厂函数:
    $mh =&factory("messageHandler");
    $mh->addMessage("Item successfully inserted");
    

    但我对此也不满意。单元测试和封装对我来说变得越来越重要,在我的理解中,全局/单例背后的逻辑破坏了 OOP 的基本思想。

    然后当然有可能为每个对象提供许多指向它需要的帮助对象的指针,这可能是最干净、节省资源和测试友好的方式,但从长远来看,我对此的可维护性表示怀疑。

    我研究过的大多数 PHP 框架要么使用单例模式,要么使用访问初始化对象的函数。两种方法都很好,但正如我所说,我对两者都不满意。

    我想拓宽视野,了解这里存在哪些常见模式。我正在寻找来自 的关于讨论此问题的资源的示例、其他想法和指针。长期 , 真实世界看法。

    此外,我有兴趣了解专业、利基或 普通怪异问题的处理方法。

    最佳答案

    我会避免 Flavius 建议的 Singleton 方法。避免这种方法的原因有很多。它违反了良好的 OOP 原则。谷歌测试博客有一些关于单例以及如何避免它的好文章:

    http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-join-new-project.html
    http://googletesting.blogspot.com/2008/05/tott-using-dependancy-injection-to.html
    http://googletesting.blogspot.com/2008/08/where-have-all-singletons-gone.html

    备择方案

  • 服务提供者

    http://java.sun.com/blueprints/corej2eepatterns/Patterns/ServiceLocator.html
  • 依赖注入(inject)

    http://en.wikipedia.org/wiki/Dependency_injection

    和一个php解释:

    http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

  • 这是一篇关于这些替代方案的好文章:

    http://martinfowler.com/articles/injection.html

    实现依赖注入(inject)(DI):
  • 我相信你应该ask what is needed in the constructor for the object to function :new YourObject($dependencyA, $dependencyB);
  • 您可以手动提供所需的对象(依赖项)( $application = new Application(new MessageHandler() )。但是您也可以使用 DI 框架(维基百科页面提供了 links to PHP DI frameworks )。

    重要的是你只传递你实际使用的东西(调用一个 Action ),而不是你简单地传递给其他对象的东西,因为他们需要它。这是“鲍勃叔叔”(罗伯特·马丁)最近发表的一篇讨论 manual DI vs using framework 的帖子.

  • 关于 Flavius 解决方案的更多想法。我不希望这篇文章成为反帖,但我认为了解为什么依赖注入(inject)至少对我来说比全局更好是很重要的。

    即使它不是“真实的”Singleton实现,我仍然认为 Flavius 弄错了。 Global state is bad .请注意,此类解决方案也使用 difficult to test static methods .

    我知道很多人都这样做了,批准了它并使用了它。但是阅读 Misko Heverys 的博客文章 (a google testability expert),重新阅读并慢慢消化他所说的内容确实改变了我对设计的看法。

    如果您希望能够测试您的应用程序,您需要采用不同的方法来设计您的应用程序。当你进行测试优先编程时,你会遇到这样的问题:“接下来我想在这段代码中实现日志记录;让我们首先编写一个记录基本消息的测试,然后提出一个测试,强制您编写和使用无法替换的全局记录器。

    我还在struggling根据我从该博客获得的所有信息,实现起来并不总是那么容易,而且我有很多问题。但是在我掌握了 Misko Hevery 所说的内容之后,我无法回到我之前所做的事情(是的,全局状态和单例(大 S)):-)

    关于design-patterns - 在 PHP 项目中,存在哪些模式来存储、访问和组织辅助对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1812472/

    相关文章:

    php - 使整个网站的页眉、侧边栏和页脚保持不变

    actionscript-3 - 在这个简单的例子中,如何思考 "Tell, don' t ask”?

    PHP - 从对象实例调用静态函数有效吗?

    php - 当用户被重定向时,与 MySQL 的连接会自动关闭吗?

    java - 设计模式 - 强制子类的某些行为

    javascript - 从循环运行异步函数

    c++ - 为什么设计器生成的嵌入为 "Aggregation"的 UI 类无法实现自定义插槽?

    php - JOIN 显示重复结果? :/

    javascript - 如何在单击按钮时将 Javascript 数组传递到 PHP 数组?

    php - 为什么单例在 PHP 环境下这么糟糕?