就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the help center为指导。
10 年前关闭。
锁定。这个问题及其答案是locked因为这个问题是题外话,但具有历史意义。它目前不接受新的答案或互动。
在基于 PHP 的面向对象的项目中,您如何组织和管理您的助手对象,例如数据库引擎、用户通知、错误处理等?
假设我有一个大型 PHP CMS。
CMS 分为不同的类。几个例子:
等等。
我正在处理一个永恒的问题,即如何最好地使需要它的系统的每个部分都可以访问这些对象。
许多年前,我的第一个方法是拥有一个 $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
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):
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/