1. 程式人生 > 實用技巧 >PHP設計模式之註冊模式(Registry)程式碼例項大全(20)

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

目的

目的是能夠儲存在應用程式中經常使用的物件例項,通常會使用只有靜態方法的抽象類來實現(或使用單例模式)。需要注意的是這裡可能會引入全域性的狀態,我們需要使用依賴注入來避免它。

例子

  • 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 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 網際網路架構師成長之路*「設計模式」終極指南

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

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

★如果喜歡我的文章,想與更多資深開發者一起交流學習的話,獲取更多大廠面試相關技術諮詢和指導,歡迎加入我們的群啊,暗號:phpzh(君羊號碼856460874)。

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

內容不錯的話希望大家支援鼓勵下點個贊/喜歡,歡迎一起來交流;另外如果有什麼問題 建議 想看的內容可以在評論提出