PHP设计模式之注册树模式

为什么使用注册树模式

最近公司项目有一个需求,在不同模块中调用用户的信息,就是根据需要将用户的各种信息调出来使用。原先的做法是,每个模块需要用户的时候都从数据库中调用。这样的做法,不断地调用数据库比较多余。如果将需要调用的用户信息,缓存到一个全局数组中,然后在需要的时候再调用,这样数据库的操作就会大大减少。于是就用到了注册树模式。

注册树模式(Registry Pattern ):注册树模式为应用中经常使用的对象创建一个中央存储器来存放这些对象 —— 通常通过一个只包含静态方法的抽象类来实现(或者通过单例模式)。也叫做注册器模式

为什么需要注册树模式

解决常用对象的存放问题,实现类似于全局变量的功能。

注册树模式UML图

简单实例

<?php
//User类用于测试
class User{}

//注册树类
class Register
{
    protected static $objects;  //用于存放实例
    //存入实例方法
    static public function set($key, $object)
    {
        self::$objects[$key] = $object;
    }
    //获取实例方法
    static public function get($key)
    {
        if (!isset(self::$objects[$key]))
        {
            # 如果不存在抛出错误
            return false;
        }
        return self::$objects[$key];
    }
    //删除实例方法
    static public function _unset($key)
    {
        unset(self::$objects[$key]);
    }
}


// 实例化
$user = new User;
//存入实例
Register::set('User',$user);
//查看实例
var_dump(Register::get('User'));
//删除实例
Register::_unset('User');
//再次查看实例
var_dump(Register::get('User'));


解释

注册树经常与单例模式一起使用,先查看注册树上是否有该实例,有就直接使用,没有就生成一个实例,并挂到树上。有些时候我们还可以这样做,让get方法如果get不到实例的时候就自动new一个存放起来,这样我们使用时就不用管有没有存放过这个实例,反正没有的话get方法也会帮我们存放。

//获取实例方法
static public function get($key)
{
    if (!isset(self::$objects[$key]))
    {
        self::$objects[$key] = new $key;
    }
    return self::$objects[$key];
}

但是比较好的实践是 在注册的时候将需要注册的实例都挂到树上,等到需要调用的时候,再从注册树上调用;若树上不存在则直接get 不到,这直接返回错误。这样做法的原因是,在数据非常多的情况下,如果未将实例挂在树上,则get无论什么情况,都能直接从数据库中调取数据,数据库的查询量比较大。

微信打赏微信打赏
支付宝打赏支付宝打赏

评论: