Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

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 

我要啦免费统计