一尘不染

在PHP项目中,存在哪些模式来存储,访问和组织帮助器对象?

php

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

假设我有一个大型PHP CMS。CMS分为各种类别。一些例子:

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

等等

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

多年前,我的第一个方法是创建一个$ application全局变量,其中包含这些类的初始化实例。

global $application;
$application->messageHandler->addMessage("Item successfully inserted");

然后,我切换到Singleton模式和工厂功能:

$mh =&factory("messageHandler");
$mh->addMessage("Item successfully inserted");

但我也不满意。单元测试和封装对我来说变得越来越重要,而据我所知,全局/单子背后的逻辑破坏了OOP的基本思想。

然后当然可以给每个对象一些指向它所需的辅助对象的指针,这可能是最干净,节省资源和易于测试的方式,但是从长远来看,我对此表示怀疑。

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

我想扩大一下这里存在哪些常见模式的视野。我正在寻找可以从 长期真实世界的 角度讨论此问题的示例,其他想法和指向资源的指针。

另外,我很想听听有关此问题的专业,利基或 简单怪异的 方法。


阅读 285

收藏
2020-05-26

共1个答案

一尘不染

实现依赖项注入(DI):

  • 我相信您应该问构造函数中该对象需要什么:new YourObject($dependencyA, $dependencyB);

  • 您可以 手动$application = new Application(new MessageHandler())提供所需的对象(依赖项)。但是您也可以使用 DI框架 (维基百科页面提供了指向PHP DI框架的链接。

重要的是,您仅传递您实际使用的内容(调用操作),而不传递您仅传递给其他对象的内容,因为它们需要它们。

关于Flavius解决方案的更多想法。我不希望这个帖子成为反帖子,但我认为重要的是要弄清为什么依赖注入至少在我看来比全局变量更好。

即使这不是“真正的” Singleton实现,我仍然认为Flavius弄错了。全球状况不好。请注意,此类解决方案还使用难以测试的静态方法

我知道很多人会这样做,批准并使用它。但是阅读Misko
Heverys的博客文章(一位Google可测试性专家),重新阅读它并慢慢地消化他所说的内容确实改变了我对设计的看法。

如果您希望能够测试您的应用程序,则需要采用其他方法来设计应用程序。当您进行测试优先编程时,您将遇到如下困难:’接下来,我想在这段代码中实现日志记录;让我们先编写一个记录基本消息的测试”,然后提出一个强制您编写和使用不可替代的全局记录器的测试。

我仍然在努力地从博客中获取所有信息,并且实施起来并不总是那么容易,而且我有很多问题。但是,在我掌握了Misko
Hevery所说的话之后,我无法回到以前做过的事情(是的,全局状态和Singletons(大S)):-)

2020-05-26