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("..."); ?> 但正如您所看到的,即使我们不需要它们,我们也会将实例添加到注册表中(是的,这完全取决于性能). 这就是我要找的…… <? 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()方法包含连接常量等. 我真的很抱歉我的英语,但我希望你能清楚. 谢谢. 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |