我们都知道单身人士有多糟糕,因为他们隐藏了依赖关系和其他原因.
但是在一个框架中,可能有许多对象只需要实例化一次并从任何地方调用(logger,db等).
为了解决这个问题,我被告知使用一个所谓的"对象管理器"(或像symfony这样的服务容器),它在内部存储对服务的每个引用(记录器等).
但为什么服务提供商不像纯粹的单身人士那样糟糕?
服务提供商也隐藏了依赖关系,他们只是创建了第一个istance.所以我真的很难理解为什么我们应该使用服务提供商而不是单身人士.
PS.我知道不要隐藏依赖关系我应该使用DI(如Misko所述)
我想补充一点:这些天单身人士不是那么邪恶,PHPUnit的创建者在这里解释:
DI + Singleton解决了这个问题:
<?php
class Client {
public function doSomething(Singleton $singleton = NULL){
if ($singleton === NULL) {
$singleton = Singleton::getInstance();
}
// ...
}
}
?>
Run Code Online (Sandbox Code Playgroud)
这很聪明,即使这根本不能解决所有问题.
除DI和Service Container之外是否有任何可接受的解决方案来访问此帮助程序对象?
我并不想创建一个关于单比静态比全球要好,等我看了几十个关于SO类似问题的问题,但我不能想出一个回答这个具体问题更好的讨论,所以我希望有人可以用一个(或多个)真实的简单例子来回答这个问题,而不仅仅是理论上的讨论.
在我的应用程序中,我有一个典型的DB类来抽象数据库层并在数据库上执行任务而无需在代码中随处写入mysql_connect / mysql_select_db / mysql...
我可以把这个类写成静态类:
class DB
{
private static $connection = FALSE; //connection to be opened
//DB connection values
private static $server = NULL; private static $usr = NULL; private static $psw = NULL; private static $name = NULL;
public static function init($db_server, $db_usr, $db_psw, $db_name)
{
//simply stores connections values, without opening connection
}
public static function query($query_string)
{
//performs query over alerady opened connection, if not open, it opens connection …Run Code Online (Sandbox Code Playgroud) 我已经开始重构一个小应用程序来使用一个小的DI容器,而不是使用$ registry :: getstuff(); 在我的课程中调用我将它们注入容器中.
这提出了两个问题,
Q1 - >我扩展了Pimple DI类并创建了一个容器,其中包含特定于需要DI的每个对象的依赖项.然后我将整个shebang对象提供给它,并在构造函数中将其解析为将DI的对象分配给我正在构建的对象的类属性.
我应该在新对象()调用中分离对象吗?我刚刚发现这样比较容易,但现在看到我是一个单人团队,我只想确认我有适当的方法.
Q2 - >我发现如果我在几个主要类上执行此操作,我遍布的$ registry对象将是无效的,这是否是使用DI的正常结果,没有更多的注册表?我可能在容器中注入了一个或两个单例,但它看起来就像我将需要的一样,甚至那些可以很容易地被淘汰,因为DI有一个share()属性,它返回对象的同一个实例,有效地消除了需要对于单身人士.这是摆脱应用程序需要注册表/单身人士的方式,因为如果它是这样的很容易.