何时应使用单一实例模式和静态方法


When should you use singleton pattern and static methods?

什么时候应该使用单例模式和静态(静态方法和静态属性)?

我读过很多博客/教程/评论,总是说单例模式,所以我从不使用它。

但同样,有许多php框架正在使用单例,例如Laravel,它现在越来越流行。

例如,在拉拉维尔,

$app->singleton(
    'Illuminate'Contracts'Http'Kernel',
    'App'Http'Kernel'
);
$app->singleton(
    'Illuminate'Contracts'Console'Kernel',
    'App'Console'Kernel'
);
$app->singleton(
    'Illuminate'Contracts'Debug'ExceptionHandler',
    'App'Exceptions'Handler'
);

如果你检查一下,你可以单例在Laravel中大量使用(似乎)。这到底是怎么回事呢?

单例是 STUPID 中的第一个字母,我们应该尽可能避免理解。

但我相信有些程序员会强烈反对——Its the best way to do it in that situation - if you need to use them, use them. Simple as that.

那么,在什么情况下,如果您不同意 STUPID,您应该使用单例?

此外,在拉拉维尔,你会看到很多这样的,

$users = DB::table('users')->get();

猜它要么是单例方法,要么是静态方法(我不太擅长 Laravel——刚刚开始研究它)。

它似乎很容易使用,但是在测试中呢,它们会很难测试吗?

我也在其他框架中看到这种方法(DB::something(...))。他们似乎不是一个好主意,但我相信很多人也会不同意。那么在什么情况下你应该使用静态方法呢?

我建议,单例的最佳用途是当你需要配置一个构建成本高昂的资源时,这是实际的

在大多数情况下,您会发现框架倾向于围绕数据库连接创建单例。这允许在整个框架中重用数据库连接的资源,而无需在每个查询中重新生成与配置的连接。

laravel使用像DB::table这样的静态方法的方式是,它只是单例的包装器,或者他们喜欢称之为控制容器的反转(http://laravel.com/docs/4.2/ioc)。其目的是允许您拥有一个静态接口,如果您需要使用其他资源,您可以更改后端单例提供程序。

要回答最后一部分,静态方法的最佳目的是对不需要实例存在的类的静态或常量属性运行一些计算(考虑Java:何时使用静态方法)。