【设计模式】AB-单例模式(Singleton Pattern)

前言

在有些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。

了解php内存管理的人都知道,一个类文件(xxxx.class.php)在加载后会先进入代码区以字符串的形式保存起来,在实例化的时候才会在堆中生成对应的对象占用部分内存。在有些场景中,为了防止对象被重复实例化,会使用此模式来保证只能创建一个实例。

如:在封装一个数据库连接交互的类库的时候,为了避免多次连接数据库,可能会使用到单例模式来保证一次脚本运行只创建一个连接,或者使用单例模式创建一个数据库连接池,保证数据库连接的可用性。

实现方法

  1. 私有化构造方法 __construct() 防止对象被直接实例化

  2. 私有化克隆方法 __clone() 防止通过克隆的手段重复实例化

  3. 暴露一个获取单例的公有的静态方法,一般来说命名为 getInstance()

  4. 使用一个私有静态变量来保存此单例

demo

因为静态方法比较简单,此处仅演示CliLog

CliLog

<?php

namespace Demo\ABSingleton\Classes;

class CliLog
{
    private static $instance = null;

    /**
     * 私有化构造方法,防止从外部实例化自己
     * CliLog constructor.
     */
    private function __construct()
    {
    }

    /**
     * 私有化克隆方法,防止通过克隆的手段实例化自己
     */
    private function __clone()
    {
    }

    /**
     * 暴露在外的获取实例的方法
     * @return CliLog|null
     */
    public static function getInstance()
    {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function log($str)
    {
        echo $str . PHP_EOL;
    }
}

demo:

<?php

namespace Demo\ABSingleton;

require_once __DIR__ . '/../../vendor/autoload.php';

use Demo\ABSingleton\Classes\CliLog;

$log = '这是一个日志';

//  通过暴露的实例化方法来实例化自己
$fileLog = CliLog::getInstance();

$fileLog->log($log);

输出

[root@iZbp1acp86oa3ixxw4n1dpZ ABSingleton]# php demo.php 
这是一个日志

程序幼儿员-龚学鹏
请先登录后发表评论
  • latest comments
  • 总共0条评论