PHP設計模式之註冊模式(Registry)代碼實例大全(20)

目的

目的是可以存儲在應用程序中常常使用的對象實例,一般會使用只有靜態方法的抽象類來實現(或使用單例模式)。須要注意的是這裏可能會引入全局的狀態,咱們須要使用依賴注入來避免它。php

例子

  • Zend 框架 1:Zend_Registry 實現了整個應用程序的 logger 對象和前端控制器等前端

  • Yii 框架:CWebApplication 具備所有應用程序組件,例如 CWebUser,CUrlManager 等。laravel

UML圖

★官方PHP高級學習交流社羣「點擊」管理整理了一些資料,BAT等一線大廠進階知識體系備好(相關學習資料以及筆面試題)以及不限於:分佈式架構、高可擴展、高性能、高併發、服務器性能調優、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等多個知識點高級進階乾貨面試

代碼

  • Registry.php
<?php

namespace DesignPatterns\Structural\Registry;

/**
 * 建立註冊表抽象類。
 */
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 DesignPatterns\Structural\Registry\Tests;

use DesignPatterns\Structural\Registry\Registry;
use stdClass;
use PHPUnit\Framework\TestCase;

/**
* 建立自動化測試單元。
*/
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 互聯網架構師成長之路*「設計模式」終極指南sql

PHP 互聯網架構師 50K 成長指南+行業問題解決總綱(持續更新)shell

面試10家公司,收穫9個offer,2020年PHP 面試問題設計模式

★若是喜歡個人文章,想與更多資深開發者一塊兒交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入咱們的羣啊,暗號:phpzh(君羊號碼856460874)。數組

2020年最新PHP進階教程,全系列!服務器

內容不錯的話但願你們支持鼓勵下點個贊/喜歡,歡迎一塊兒來交流;另外若是有什麼問題 建議 想看的內容能夠在評論提出架構

相關文章
相關標籤/搜索