php – 注册表模式和注册对象的惰性实例化

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了php – 注册表模式和注册对象的惰性实例化脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
让我们假设我们有注册表模式……

<?PHP

class Registry
{

PRivate static $objects     = array();
private static $instance    = null;

public static function getInstance() {
    if (self::$instance == null) {
        self::$instance = new Registry();
    }
    return self::$instance;
}

protected function _get($key) {
    return ($this->objects[$key]) ? $this->objects[$key] : null;
}

protected function _set($key,$val) {
    $this->objects[$key] = $val;
}

public static function get($key) {
    return self::getInstance()->_get($key);
}

public static function set($key,$object) {
    return self::getInstance()->_set($key,$object);
}

}
?>

使用这种实现真的很容易……

<?
Registry::set('db',$db_client);
Registry::set('redis',$redis_client);

//Using registered objects is really easy
Registry::get('db')->query("...");
Registry::get('redis')->get("...");
?>

但正如您所看到的,即使我们不需要它们,我们也会将实例@L_777_2@到注册表中(是的,这完全取决于性能).
所以,问题是……如何修改注册表模式以便能够进行惰性实例化?

这就是我要找的……

<?
class Registry
{

private static $objects     = array();
private static $instance    = null;

public static function getInstance() {
    if (self::$instance == null) {
        self::$instance = new Registry();
    }
    return self::$instance;
}

protected function _db() {
    if (!$this->objects['db']) {
        $this->objects['db'] = new DatabaseAdapter(DB_HOST,DB_NamE,DB_USER,DB_PASSWORD);
    }
    return $this->objects['db'];
}

protected function _redis() {
    if (!$this->objects['redis']) {
        $this->objects['redis'] = new Redis(REDIS_HOST,REDIS_DB,REDIS_USER,REDIS_PASSWORD);
    }
    return $this->objects['redis'];
}

public static function db() {
    return self::getInstance()->_db();
}

public static function redis() {
    return self::getInstance()->_redis();
}

}
?>

如您所见,DatabaseAdapter()或Redis()仅在我们请求它们时创建.一切似乎都没问题,但你可以看到它不是一个独立的类,因为_db(),_ redis()方法包含连接常量等.
怎么避免呢?如何在注册表类中定义注册方法以将Registy类和其中的对象分开?

我真的很抱歉我的英语,但我希望你能清楚.

谢谢.

PS:上面的所有代码都写了1分钟.以前并没有经过测试.

解决方法

如果使用全局常量,则始终依赖于全局范围.这无关紧要.此外,即使您不使用常量,您仍然依赖于Registry中的Database类.如果要解散这些依赖项,可以在要创建的类上使用Factory方法

public function get($service)
{
    if( !this->_data[$service] ) {
        // requires PHP 5.2.3
        this->_data[$service] = call_user_func($service .'::create');
    }
    return this->_data[$service];
}

因此,如果你得到(‘DB’),代码将尝试在你想要创建的类中调用静态DB :: create()方法.但就像我说的,如果你使用全局常量进行配置,你只需将问题移到另一个类中.

您的db类可能如下所示:

class DB
{
    protected static $_config;
    public static setConfig(array $config)
    {
        self::_config = $config;
    }
    public static create()
    {
        return new self(
            self::config['host'],self::config['db'],self::config['user'],self::config['pass']);
    }
}

配置可以存储在外部配置文件中,您可以在引导期间加载并设置为DB类,例如,

DB::setConfig(parse_ini_file('/path/to/db-config.ini'));

这样做的缺点是,您必须在整个地方添加create()方法,并且所有类必须能够存储自己的配置.您可以将这些职责集中到Builder pattern中.但是如果您这样做,那么无论如何都要实现IoC Container,所以请查看以下资

> Fabien Potencier: What is Dependency Injection
> Martin Fowler: Inversion of Control Containers and the Dependency Injection pattern
> Design pattern – Inversion of control and Dependency injection

脚本宝典总结

以上是脚本宝典为你收集整理的php – 注册表模式和注册对象的惰性实例化全部内容,希望文章能够帮你解决php – 注册表模式和注册对象的惰性实例化所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。