Day32. 范例:资料库连线(单例模式)

本文同步更新於blog

需求一:客户想要能与资料库连线的类别

<?php

namespace App\SingletonPattern\DBConnection;

class DBConnection
{
    public function __construct()
    {
    }
}

<?php

namespace App\SingletonPattern\DBConnection;

class Program
{
    /**
     * @return DBConnection
     */
    public function getDBConnection()
    {
        return new DBConnection();
    }
}


需求二:客户说希望能修改成只建立唯一的连线。

<?php

namespace App\SingletonPattern\DBConnection;

class DBConnection
{
    private static $instance = null;

    /**
     * 仅有私有的建构函式,让外界仅能以 getInstance() 呼叫
     */
    private function __construct()
    {
    }

    /**
     * 避免克隆後,生成两个实例
     */
    private function __clone()
    {
    }

    /**
     * 避免反序列化後,生成两个实例
     */
    private function __wakeup()
    {
    }

    /**
     * 透过公开的静态方法取得实例
     *
     * @return DBConnection
     */
    public static function getInstance()
    {
        if (static::$instance === null) {
            static::$instance = new self();
        }

        return self::$instance;
    }
}

<?php

namespace App\SingletonPattern\DBConnection;

class Program
{
    /**
     * @return DBConnection
     */
    public function getDBConnection()
    {
        return DBConnection::getInstance();
    }
}

在这里我们一共用了两个技巧:

  1. 透过公开的静态方法,呼叫私有的建构函式,
    来保证 DBConnection 的唯一。

  2. 在 getInstance() 中,我们会判断 $instance 是否为 null,
    才决定是否实例化,为单例模式中Lazy Initialization的形式。


单例模式还有以下其他形式(处理多线程):

  • Eager Initialization (类别 $instance 一开始就建立,PHP 貌似不支援)
  • Synchronized(同步方法)
  • Double-Checked Locking(双重检查加锁)

在 PHP 中,web 环境的每一个 request 都是独立的线程,
而 cli 环境,则需装 pthreads 才能实现多线程。


因为 PHP 鲜少使用多线程,算是巧妙地闪躲了单例模式的使用问题。
将来有机会会以其他程序语言,再次撰写相关范例。

最後附上类别图:
https://ithelp.ithome.com.tw/upload/images/20201017/20111630alr98fawiu.png
(注:若不熟悉 UML 类别图,可参考UML类别图说明。)

ʕ •ᴥ•ʔ:看似简单,背後却有许多细节的反模式。


<<:  远端系列-5:如何拉回远端数据库的档案?

>>:  Longest Increasing Subsequence (最长递增子序列)

Hello, World!

print("This line will be printed.") x = ...

Day 25 - 介绍 OSPF

今天我们来配 OSPF。 OSPF 是一种 IGP (Interior Gateway Protoc...

Day30 MANO开源专案使用之kube5gnfvo - 使用篇

那麽今天是最後一天了,我们就来做一个布署测试吧!昨天以介绍了关於Template的内容以及主要会使用...

Progressive Web App 架构模式: App Shell Model 概念说明 (12)

什麽是 App Shell? App Shell 乍听之下是一种技术,实际上是 Web App 架构...

你是谁、你的过去都不重要,成功的能力永远都从你开始。

你是谁、你的过去都不重要,成功的能力永远都从你开始。 It doesn’t matter who y...