PHP 單例模式

2022-05-05 11:26 更新

注:?jiǎn)卫J娇赡鼙徽J(rèn)為是一種“反模式”。為了獲得更好的可測(cè)試性和可維護(hù)性,建議使用依賴注入。

目標(biāo)

讓應(yīng)用只存在一個(gè)對(duì)象的實(shí)例,處理所有的調(diào)用。

例子

  • 數(shù)據(jù)庫(kù)連接器
  • 日志記錄器
  • 應(yīng)用程序的鎖定文件(Lock file,理論上整個(gè)應(yīng)用應(yīng)該只有一個(gè)鎖文件)

UML 圖

Alt Singleton UML Diagram

代碼

Singleton.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Singleton;

use Exception;

final class Singleton
{
    private static ?Singleton $instance = null;

    /**
     * gets the instance via lazy initialization (created on first usage)
     */
    public static function getInstance(): Singleton
    {
        if (static::$instance === null) {
            static::$instance = new static();
        }

        return static::$instance;
    }

    /**
     * is not allowed to call from outside to prevent from creating multiple instances,
     * to use the singleton, you have to obtain the instance from Singleton::getInstance() instead
     */
    private function __construct()
    {
    }

    /**
     * prevent the instance from being cloned (which would create a second instance of it)
     */
    private function __clone()
    {
    }

    /**
     * prevent from being unserialized (which would create a second instance of it)
     */
    public function __wakeup()
    {
        throw new Exception("Cannot unserialize singleton");
    }
}

測(cè)試

Tests/SingletonTest.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Singleton\Tests;

use DesignPatterns\Creational\Singleton\Singleton;
use PHPUnit\Framework\TestCase;

class SingletonTest extends TestCase
{
    public function testUniqueness()
    {
        $firstCall = Singleton::getInstance();
        $secondCall = Singleton::getInstance();

        $this->assertInstanceOf(Singleton::class, $firstCall);
        $this->assertSame($firstCall, $secondCall);
    }
}


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)