我们在面试过程中经常碰到的一道笔试题就是手写单例(singleton)模式,本文详细讲解了单例模式的两种实现形式。
单例(singleton)模式,当你实例化一个对象时,它可以确保你实例化的这个类将仅有一个实例。
当你使用单例模式第一次调用对象时,它就会被实例化,之后每一次调用都将返回同一个对象。单例模式代表在应用程序不同部分被再三使用的资源。其中常见的示例包括数据库连接和配置信息。
单例最重要的方面在于对创建实例的限制能力。如果不这样做,潜在的多个实例将被创建。
单例模式实现方式1:
class Database
{
private static $instance = null;
private function __construct()
{
}
public static function getInstance()
{
if (!(self::$instance instanceof Database)) {
self::$instance = new Database();
}
return self::$instance;
}
}
实现单例有 3 个关键点:
- 使用一个静态成员来保持一个单例实例,在这个例子中,我们有一个私有的 Database::$instance 属性。
- 一个私有的__construct()将决定这个类只能被本身所包含的静态方法实例化。
- Database::getInstance()静态方法将用于数据库类。当它被调用时,DB::getInstance() 将实例化一个 Database 类的对象并将这个对象指定给 Database:$instance 属性,然后返回这个对象,或只是返回先前实例化的对象。
我们之所以使用单例模式,是因为静态方法可以在全局范围内被访问,无论哪里,当我们需要一个数据库连接时,只需调用 Database::getinstance() 即可。
自 PHP 5.4.0 起,PHP 实现了一种代码复用的方法,称为 trait。
Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制,使开发人员能够自由地在不同层次结构内独立的类中复用 method。Trait 和 Class 组合的语义定义了一种减少复杂性的方式,避免传统多继承和 Mixin 类相关典型问题。
单例模式实现方式2:
trait Singleton
{
static $instance = null;
public static function getInstance()
{
$class = __CLASS__;
if (!(self::$instance instanceof _CLASS_)) {
self::$instance = new $class();
}
return self::$instance;
}
}
class DB
{
use Singleton;
private function __construct()
{
}
}