PHP设计模式之详记注册树模式

作者: 温新

分类: 【设计模式】

阅读: 2441

时间: 2020-10-13 14:21:29

一、什么是注册树模式

注册树模式又叫注册模式、注册器模式。注册树模式是将经常使用到的对象实例挂到一颗全局的树上,需要使用时从数树上取出即可。

举个栗子:有一个空的工具箱。需要维修东西,因此买了扳手和螺丝刀等工具,将它们放到空的工具箱中。

1、把工具放到工具箱中可以理解为对象上树

2、需要某个或某些工具时,从工具箱中取出来,可以理解为获取对象树中的对象

3、使用工具去维修物品,可以理解为使用对象

注册树模式不在二十四种设计模式当中,但它是一个非常实用的设计模式,如Laravel、ThinkPHP5.1/6都使用到了它。 理解注册树模式对于去理解框架源码非常有帮助。

二、代码实现

Singleton.php

<?php

/**
 * 单例模式
 */
class Singleton
{
    private static $instance = null;

    private function __construct() {}

    private function __clone() {}

    private function __wakeup() {}

    /**
     * getInstance 唯一获取实例对象的静态方法
     * 
     * @param  String $className 类名
     * @return object 唯一实例对象
     */
    public static function getInstance($className)
    {
        // 类名首字母大写
        $className = ucfirst($className);

        // 判断实例对象是否是该类的实例,如果是,说明已经实例化
        // 则直接返回
        if (self::$instance instanceof $className) {
            return self::$instance;
        }

        // 若不是该类的实例,则还没有进行实例化,则进行类实例
        return self::$instance = new $className();
    }

}

Factory.php

<?php
/**
 * 工厂模式
 */
class Factory
{
    /**
     * make 生产对象
     * 
     * @param  string $className 类名
     * @return object 实例对象
     */
    public static function make($className)
    {
        return Singleton::getInstance($className);
    }
}

Register.php

<?php
/**
 * 注册树模式
 */
class Register
{
    // 对象树池数组
    private static $objects = [];

    /**
     * set 设置对象入对象树池
     * 
     * @param  string $alias  对象别名
     * @param  object $object 对象
     * @return [type]         [description]
     */
    public static function set($alias , $object)
    {
        // 将对象挂到对象树池子上
        self::$objects[$alias] = $object;
    }

    /**
     * get 取出对象
     * 
     * @param  string $alias 对象别名
     * @return object 对象实例
     */
    public static function get($alias)
    {
        // 从对象树池中取出对象
        return self::$objects[$alias];
    }

    /**
     * destroy 销毁对象
     * 
     * @param  string $alias 对象别名
     */
    public static function destroy($alias)
    {
        unset($objects[$alias]);
    }   
}

User.php

<?php

// 普通用户类
class User
{
    public function say()
    {
        return '啊哈哈哈,揣摩看看~~~我是怎么出来的~~~';
    }
}

Index.php

<?php

include './Singleton.php';
include './Factory.php';
include './Register.php';
include './User.php';

class IndexController
{
    public function index()
    {
        // 将对象挂载到对象树池中
        Register::set('user' , Factory::make('User'));
        // 从对象树池中获取对象
        $user = Register::get('user');
        // 调用user类的方法
        echo $user->say();
    }

    // 测试实例多个对象是否唯一
    public function test()
    {
        Register::set('user1' , Factory::make('User'));
        Register::set('user2' , Factory::make('User'));

        $user  = Register::get('user');
        $user1 = Register::get('user1');
        $user2 = Register::get('user2');

        // 可见,只有一个实例对象
        var_dump($user);    // object(User)#2 (0) { }
        var_dump($user1);   // object(User)#2 (0) { }
        var_dump($user2);   // object(User)#2 (0) { }
    }
}


$idx = new IndexController();
echo $idx->index();
$idx->test();

我是小白,期待和优秀的你一起同行!

小白

2020年10月13日

请登录后再评论