对于注册树模式的理解

PHP注册树模式主要用于创建对象的时候将我们的对象与相应的变量进行绑定,其实就相当于我们平常说的IOC[服务容器],DI[依赖倒置],例如YII2框架的IOC就是使用了注册树模式进行对象管理的,查看了下Laravel的底层Container实现也是注册树模式,最大好处就是将我们创建对象的步骤交给容器去管理,降低我们依赖关系模块的耦合度,方便代码的管理,结构更加清晰。
使用注册树模式,我们创建对象的时候,将这件事情交给我们的容器去做,使得我们有依赖关系的模块耦合度降低,整个系统代码的耦合性大大降低,项目维护更加方便,项目的结构也更加清晰。—————-[来自另一位大神的讲解]


学习借鉴位置GIT分享
解决全局共享和交换对象的问题。实际上就是把实例好的对象放进一个数组,在任何地方要用的时候就去出来。就好比有一课树,我们把new好的 $GF1,$GF2......一个一个挂上去,要用的时候再取出来。

class Register
{
    protected static $objects;

    /**
     * 把对象映射到树上
     * @param string $alias  对象的别名
     * @param array $object 储存所有对象
     */
    static function set($alias, $object)
    {
        self::$objects[$alias] = $object;
    }

    /**
     * 把对象从树上移除
     * @param  string $alias 对象的别名
     * @return [type]        [description]
     */
    function _unset($alias)
    {
        unset(self::$objects[$alias]);
    }
}

unset在PHP中是关键字,所以用_unset代替。这样的话我们就要在工厂类中用一下Register::set()方法,把new好的对象挂树上。为了调用方便,Register中还需要一个get()方法来取对象。


static function get($key)
 {
     if (!isset(self::$objects[$key]))
     {
         return false;
     }
     return self::$objects[$key];
 }

这样我们也就不用再去使用单例模式了,直接从注册器中取Register::get()
Laravel中用了更优雅的方式。

<?php namespace Illuminate\Contracts\Auth;

interface Registrar {

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    public function validator(array $data);

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    public function create(array $data);

}

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

这里写图片描述
示例代码
Registry.php

<?php

namespace DesignPatterns\Structural\Registry;

/**
 * class Registry
 */
abstract class Registry
{
    const LOGGER = 'logger';

    /**
     * @var array
     */
    protected static $storedValues = array();

    /**
     * sets a value
     *
     * @param string $key
     * @param mixed  $value
     *
     * @static
     * @return void
     */
    public static function set($key, $value)
    {
        self::$storedValues[$key] = $value;
    }

    /**
     * gets a value from the registry
     *
     * @param string $key
     *
     * @static
     * @return mixed
     */
    public static function get($key)
    {
        return self::$storedValues[$key];
    }

    // typically there would be methods to check if a key has already been registered and so on ...
}

Tests/RegistryTest.php

<?php

namespace DesignPatterns\Structural\Registry\Tests;

use DesignPatterns\Structural\Registry\Registry;

class RegistryTest extends \PHPUnit_Framework_TestCase
{

    public function testSetAndGetLogger()
    {
        Registry::set(Registry::LOGGER, new \StdClass());

        $logger = Registry::get(Registry::LOGGER);
        $this->assertInstanceOf('StdClass', $logger);
    }
}

如果看不懂代码结构可以参考这个链接

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐