主要目标是在应用程序的任何位置(控制器,映射器,模型,助手等)提供核心类(使用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);
有没有更好的方法来做我想要的?有什么缺点吗?
答案 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中调用你的注册表会很糟糕,因为该类可能不知道注册表的存在,但这种方式看起来还不错。