这是一个很好的使用注册表?

时间:2011-02-04 07:26:44

标签: php dependency-injection

主要目标是在应用程序的任何位置(控制器,映射器,模型,助手等)提供核心类(使用params实例化)。

例如,我们有一个依赖于Database对象的mapper:

class Foo_Mapper
{
    private $database;

    public function __construct(Database $database)
    {
        $this->database = $database;
    }

    public function getFoo(array $criteria)
    {
        // ...
    }
}

变体1:基本依赖注入。问题是每次我需要创建mapper时,我还需要实例化一个数据库对象(使用params)。

$database = new Database($params);

$foo_mapper = new Foo_Mapper($database);

变式2:注册表。核心对象被实例化并放入注册表中,因此每个其他对象都可以轻松访问它们。

// Somewhere in bootstrap...
$registry = Registry::getInstance();
$registry->database = new Database($params));

// Usage
$registry = Registry::getInstance();

$foo_mapper = new Foo_Mapper($registry->database);

有没有更好的方法来做我想要的?有什么缺点吗?

2 个答案:

答案 0 :(得分:1)

  

变体1:基本依赖注入。问题是每次我需要的时候   创建映射器,我还需要实例化一个数据库对象(使用params)。

或传递它。如果您使用依赖注入容器,您甚至必须手动执行此操作:您只需添加需要检索数据库的内容,并为您创建(或重用)数据库。让Container创建一个控制器,并确保在构造函数中列出依赖项。 PHP有一些不错的依赖注入容器,即:

完全披露:我写了最后一篇。

  

变式2:注册表。核心对象被实例化并相互注册   对象可以轻松访问它们。

您可以使注册表非静态,但如果您要依赖应用程序中的Registry对象,那么您可以将其保留为静态。这是一个非常可行的解决方案,有一个明显的缺点:通过查看API,您不知道哪些对象被哪些对象使用。你必须深入研究代码。

答案 1 :(得分:0)

你可以把它变成一个单身人士。像这样:

class Database
{
  private static $instance = null;
  public static getInstance()
  {
    if (self::$instance == null) self::$instance = new Database();
    return self::$instance;
  }
   // ... METHODS ... //
   // ... METHODS ... //
   //      .....      //
}

然后你可以使用 new Foo_Mapper(Database :: getInstance()); 看起来你用你的注册表做了这个。那你就不再需要你的注册表了。虽然如果你的类是由其他人编码的,你仍然需要使用像注册表这样的东西,或者为那些不使用单例模式的类创建一个帮助器类/函数。

我认为你说明的方式对我来说似乎没问题。如果你从Foo_Mapper中调用你的注册表会很糟糕,因为该类可能不知道注册表的存在,但这种方式看起来还不错。