为什么人们在他们的PHP框架中使用单例

dyn*_*mic 11 php oop frameworks dependency-injection

好吧,我正在努力理解为什么需要单身人士.

让我们举一个真实的例子:我有一个我的CMS的框架
我需要有一个记录一些信息的类(让我们坚持使用PHP).

例:

class Logger{
   private $logs = array();

   public function add($log) {
      $this->logs[]=$log;
   }      
}
Run Code Online (Sandbox Code Playgroud)

当然,这个辅助对象对于CMS的页面请求的输入生命周期必须是唯一的.
为了解决这个问题,我们将它变成一个单例(声明私有构造函数等)

但为什么像这样的阶级并不是完全静止的呢?这将解决单例模式的需要(这被认为是不好的实践)示例:

class Logger {
    private static $logs = array();

    public static function add($log) {
        self::$logs[]=$log;
    }
}
Run Code Online (Sandbox Code Playgroud)

通过使这个帮助器完全静态,当我们需要在我们的应用程序中的某处添加一个日志时,我们只需要静态地调用它:Logger::add('log 1');vs一个单独的调用,如:Logger::getInstance()->add('log 1');

希望有人能让我轻松理解为什么在PHP中使用单例而不是静态类.

编辑

感谢@James,这是一个非常好的关于单身人士与静态课程的讲座.(注意它没有解决我的问题)

dqh*_*cks 7

很多原因.

静态方法基本上是可以从任何范围调用的全局函数,这有助于难以跟踪错误.你可能根本不使用课程.

由于您不能使用__construct方法,因此可能必须在某处放置init静态方法.现在,他们的代码中的人不确定先前是否调用过init方法.他们又叫了吗?他们是否必须在代码库中搜索此调用?如果init在某处,但随后被删除或中断怎么办?您的代码中的许多位置现在依赖于调用init方法的位置.

众所周知,静态方法难以用许多单元测试框架进行单元测试.

还有很多原因,但很难将它们列出来.

如果您使用DI,则不需要单身人士.

旁注.DI允许您的类不相互依赖,而是依赖于接口.由于他们的关系没有巩固,因此以后更容易更改您的应用程序,并且一个课程打破不会破坏这两个类.

在某些情况下,单个状态类是可行的,例如,如果您的方法都不依赖于其他方法(基本上没有一个方法会改变类的状态).


sta*_*san 5

我使用单身,所以我可以告诉你为什么我这样做而不是静态功能.

单例的定义特征是它是一个只有一个实例的类.很容易看到"只是一个实例"子句而忘记看"它是一个类"子句.毕竟,它是一个普通的类对象,具有所带来的所有优点.主要是,它有自己的状态,它可以有私有函数(方法).静态函数必须以更有限或更笨拙的方式执行这两种操作.

也就是说,两者相互补充:可以利用静态函数在同一个类上返回单例.这就是我在最常用的单例中所做的事情:数据库处理程序.

现在,许多程序员都被教导说"单身人士很糟糕,不能吗?" 但忽略了骑手,过度使用的东西通常只会很糟糕.就像一个主雕刻师一样,经验丰富的程序员可以使用很多工具,而且许多工具都不会得到很多用处.我的数据库处理程序非常适合作为单例,但它是我经常使用的唯一一个.对于日志记录类,我通常使用静态方法.