全局vs函数与静态类方法

时间:2012-02-08 21:13:32

标签: php class function global

假设你有一个独特的对象,它被所有其他类和函数使用......类似于$application

您将如何在函数中访问此对象?

  1. 在每个函数中使用全局变量:

    global $application;
    $application->doStuff();
    
  2. 创建一个函数,如application(),将对象实例化为静态变量并返回它;然后在需要访问对象的任何地方使用此函数:

    application()->doStuff();
    
  3. 创建一个单例的东西,就像一个返回唯一实例的对象类中的静态方法,并使用此方法来访问该对象:

    Application::getInstance()->doStuff();
    
  4. KingCrunch& skwee:将应用程序对象作为参数传递给需要的每个函数/类

    ...
    public function __construct(Application $app, ...){
      ....
    
  5. 如果还有其他选择,请发布。我想知道哪些选项是最有效/被认为是“最佳实践”。

3 个答案:

答案 0 :(得分:4)

单身人士,上帝阶级,单片类等都是反模式,所以我建议第四种选择:依赖注入。您可以通过工厂在您的应用程序中创建application的实例(如果它没有依赖关系,甚至可能new,但这最终会使事情变得复杂化。)

然后,任何需要访问application的类都可以通过构造函数将其作为成员获取。我确信每个类都不需要访问application。记住得墨忒耳法则。

如果你需要一些通用功能,比如将一个静态字符串转换为另一个,我建议使用php的全局函数(例如,与虚拟静态类相反)。我相信它们是为此目的而设计的。

答案 1 :(得分:4)

我将它传递给所有需要的方法。 即。

function doFoo(Application $app) {
    $app->doStuff();
}

全局和单身都被认为是错误的并且将代码绑定得太多,这使得单元测试更加困难。 如果您对以下语句回答“是”,则允许使用单例时有一条规则:

  

我是否需要将全局状态引入我的应用程序并且我必须有一个给定对象的实例并且具有多个实例将导致错误

如果您对所有3个部分的回答都是肯定的,那么您可以使用单身人士。在任何其他情况下,只需将所有实例传递给所有需要它们的方法。如果你有太多的东西,可以考虑使用Context

之类的东西
class Context {
    public $application;
    public $logger;
    ....
}
========
$context = new Context();
$context->application = new Application();
$context->logger = new Logger(...);
doFoo($context);
========
function doFoo(Context $context) {
    $context->application->doStuff();
    $context->logger->logThings();
}

(如果您需要保护数据或操纵数据,或者如果您想使用延迟启动等,则可以使用getter / setter。)

祝你好运!

答案 2 :(得分:1)

或者只是把它给那些对它感兴趣的人。你提出的所有建议都像全局变量,即使你称之为3变体中的2个也不是。

在谈到这一点之前:如果你想说“那是不可能的,因为所有需要它”,或许它做得太多,可能太多,和/或知道得太多。