Zend Framework 与设计模式 (二) - registry 注册者模式
Posted on 2010-02-05 19:49 analyzer 阅读(1227) 评论(0) 编辑 收藏 举报注册者模式 (registry) 提供了一种机制,能让你在程序中有条理的存放并管理对象 (object) ,它的主要作用是防止用户滥用全局对象 (global object) 。
Registry 通常提供对象的存取,注销等方法,方便用户管理。下面来看看 Zend Framework 中 registry 的例子,这里挑选最经典的 Zend_Registry 为例 :
class Zend_Registry extends ArrayObject { ...... // Registry 私有对象是用来存储共享对象的注册者 private static $_registry = null; // Constructor 初始化为 ArrayObject 对象 // @link http://www.php.net/manual/en/class.arrayobject.php public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS) { parent::__construct($array, $flags); } // 返回默认的注册对象实例 public static function getInstance() { if (self::$_registry === null) { self::$_registry = new Zend_Registry(); } return self::$_registry; } // 销毁注册者 public static function _unsetInstance() { self::$_registry = null; } // Getter 方法,基于 ArrayObject 的 offsetGet() 方法,提取存储的实例。 public static function get($index) { $instance = self::getInstance(); ... return $instance->offsetGet($index); } // Setter 方法,基于 ArrayObject 的 offsetSet() 方法,存储实例。 public static function set($index, $value) { $instance = self::getInstance(); $instance->offsetSet($index, $value); } ...... }
上面是经过简化而得的源代码,值得注意的是 Zend_Registry 继承自 ArrayObject (参考http://www.php.net/manual/en/class.arrayobject.php) ,也就是说 Zend_Registry 完全能以数组的形式来进行操作。
以下的用法在本质上是一样的 :
Zend_Registry::set($name, $value); ...... $value2 = Zend_Registry::get($name); $registry= Zend_Registry::getInstance(); $registry[$name] = $value; ...... $value2 = $registry[$name];
另外 registry 通常可以与单元子模式 singleton 搭配使用 (singleton - 参见 "Zend Framework 与设计模式(一) - singleton 单元子模式"一章),例如 :
class singletonExample { ... // Singleton 单元子对象 public static function getInstance() { if (false == Zend_Registry::isRegistered('singletonExample')) { Zend_Registry::set('singletonExample', new self()); } return Zend_Registry::get('singletonExample'); } ... }
在 Zend_Framework 中,Zend_Registry 还扮演了框架构建者的角色。例如在 Zend_View_Helper_Translate 中,Zend_Registry 为翻译器 (translate) 视图助手提供了默认的翻译者 (translator) :
class Zend_View_Helper_Translate extends Zend_View_Helper_Abstract { ... // 获取翻译对象 // 如果当前没有设置翻译者,则尝试从注册者中根据关键词 Zend_Translate 来寻找 public function getTranslator() { if ($this->_translator === null) { require_once 'Zend/Registry.php'; if (Zend_Registry::isRegistered('Zend_Translate') === true) { $this->setTranslator(Zend_Registry::get('Zend_Translate')); } } return $this->_translator; } ... }
实际上,注册者模式 (registry) 是贯穿全局的对象管理者,也是最基础,应用最广泛的编程模式之一,更是构建框架不可或缺的一部分。
转自:http://kbs.kimbs.cn/blog/list/post/10/title/registry-pattern-in-Zend-Framework