【问题标题】:Global vs function vs static class method全局 vs 函数 vs 静态类方法
【发布时间】:2012-03-01 08:55:14
【问题描述】:

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

你将如何在你的函数中访问这个对象?

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

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

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

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

    ...
    public function __construct(Application $app, ...){
      ....
    

如果有其他选项,请发布它们。我想知道这些选项中哪一个是最有效/被认为是“最佳实践”。

【问题讨论】:

  • 您有具体问题,还是只是想列个清单?

标签: php class function global


【解决方案1】:

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

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(我必须有一个给定对象的实例)是真的:)
  • 但是有多个实例会导致程序出错?它是 A && B && C 的逻辑陈述,在您的情况下,B 为真,A 和 C 为假,因此该陈述为假 :) 我真的想不出该陈述的答案为真的情况。当我有一个 CPU 或类似的东西时,也许在编程某种微控制器时......
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    或者只是把它交给那些对它感兴趣的人。您提出的所有建议都类似于全局变量,即使您在 3 个变体中的 2 个中都不是这样称呼它。

    在此之前:如果您想说“那不可能,因为 一切 都需要它”,那么它可能做的太多、可以做的太多和/或知道的太多。

    【讨论】:

    • 这是真的,我可以将应用程序作为参数传递给需要它的每个类的 __construct。但我不知道...在该类中使用$this->application 看起来有点奇怪
    • 我也必须将该参数传递给类的每个静态方法......
    • 使用$this->property 看起来与访问依赖项的外观完全相同。关于您的第二条评论:听起来,您也有太多静态方法。
    猜你喜欢
    • 2013-07-06
    • 2012-12-02
    • 2012-08-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-01
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多