Erlo

PHP设计模式之注册模式(Registry)代码实例大全(20)

2020-09-16 22:30:41 发布   242 浏览  
页面报错/反馈
收藏 点赞

目的

目的是能够存储在应用程序中经常使用的对象实例,通常会使用只有静态方法的抽象类来实现(或使用单例模式)。需要注意的是这里可能会引入全局的状态,我们需要使用依赖注入来避免它。

例子

  • Zend 框架 1:Zend_Registry 实现了整个应用程序的 logger 对象和前端控制器等

  • Yii 框架:CWebApplication 具有全部应用程序组件,例如 CWebUser,CUrlManager 等。

UML图

★官方PHP高级学习交流社群「点击」管理整理了一些资料,BAT等一线大厂进阶知识体系备好(相关学习资料以及笔面试题)以及不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货

代码

  • Registry.php

<?php

namespace DesignPatternsStructuralRegistry;

/**
 * 创建注册表抽象类。
 */
abstract class Registry
{
    const LOGGER = 'logger';

    /**
     * 这里将在你的应用中引入全局状态,但是不可以被模拟测试。
     * 因此被视作一种反抗模式!使用依赖注入进行替换!
     *
     * @var array
     * 定义存储值数组。
     */
    private static $storedValues = [];

    /**
     * @var array
     * 定义合法键名数组。
     * 可在此定义用户名唯一性。
     */
    private static $allowedKeys = [
        self::LOGGER,
    ];

    /**
     * @param string $key
     * @param mixed  $value
     *
     * @return void
     * 设置键值,并保存进 $storedValues 。
     * 可视作设置密码。
     */
    public static function set(string $key, $value)
    {
        if (!in_array($key, self::$allowedKeys)) {
            throw new InvalidArgumentException('Invalid key given');
        }

        self::$storedValues[$key] = $value;
    }

    /**
     * @param string $key
     * 
     * @return mixed
     * 定义获取方法,获取已存储的对应键的值
     * 可视作验证用户环节,检查用户名是否存在,返回密码,后续验证密码正确性。
     */
    public static function get(string $key)
    {
        if (!in_array($key, self::$allowedKeys) || !isset(self::$storedValues[$key])) {
            throw new InvalidArgumentException('Invalid key given');
        }

        return self::$storedValues[$key];
    }
}

测试

  • Tests/RegistryTest.php

<?php

namespace DesignPatternsStructuralRegistryTests;

use DesignPatternsStructuralRegistryRegistry;
use stdClass;
use PHPUnitFrameworkTestCase;

/**
* 创建自动化测试单元。
*/
class RegistryTest extends TestCase
{
    public function testSetAndGetLogger()
    {
        $key = Registry::LOGGER;
        $logger = new stdClass();

        Registry::set($key, $logger);
        $storedLogger = Registry::get($key);

        $this->assertSame($logger, $storedLogger);
        $this->assertInstanceOf(stdClass::class, $storedLogger);
    }

    /**
     * @expectedException InvalidArgumentException
     */
    public function testThrowsExceptionWhenTryingToSetInvalidKey()
    {
        Registry::set('foobar', new stdClass());
    }

    /**
     * 注 @在此运行隔离进程:没有它的话,前一个测试单元可能已经设置它,
     * 并且测试将不能运行,这就是为什么你应该实现依赖注入,
     * 因为注入类会很容易被测试单元替代。
     *
     * @runInSeparateProcess
     * @expectedException InvalidArgumentException
     */
    public function testThrowsExceptionWhenTryingToGetNotSetKey()
    {
        Registry::get(Registry::LOGGER);
    }
}

PHP 互联网架构师成长之路*「设计模式」终极指南

PHP 互联网架构师 50K 成长指南+行业问题解决总纲(持续更新)

面试10家公司,收获9个offer,2020年PHP 面试问题

★如果喜欢我的文章,想与更多资深开发者一起交流学习的话,获取更多大厂面试相关技术咨询和指导,欢迎加入我们的群啊,暗号:phpzh(君羊号码856460874)。

2020年最新PHP进阶教程,全系列!

内容不错的话希望大家支持鼓励下点个赞/喜欢,欢迎一起来交流;另外如果有什么问题 建议 想看的内容可以在评论提出

登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认