模式对于面向对象开发是相当重要的。一种模式可以帮助我们创建能够实现特定任务的对象,成为类的职责。模式还允许我们修改某个类,但不需要修改与这个类有关系的代码,这个称为类的多态。
单例模式又称为职责模式,它用来在应用程序中创建一个单一的功能访问点。下面我们来探讨并且结结实实地掌握单例的思想还有应用。
在复杂的系统中,使用单例模式在维持应用程序状态的同步方面尤其有用。所有的单例类至少拥有以下三个元素:
- 一个标记为private的构造函数。
- 保存类的实例的静态成员变量。
- 访问这个实例的公共静态方法。
Program List:单例模式的类
<?php class Fruit { // Hold an instance of the class private static $instance; // A private constructor; prevents direct creation of object // 防止类被当作实例使用,就是无法使用此类创建对象 private function __construct() { echo 'I am constructed'; } // The singleton method public static function singleton() { if (!isset(self::$instance)) { $c = __CLASS__; self::$instance = new $c; } return self::$instance; } // Example method public function showColor() { echo 'My color is !'; } // Prevent users to clone the instance public function __clone() { trigger_error('Clone is not allowed.', E_USER_ERROR); } } // This would fail because the constructor is private //$test = new Fruit(); // This will always retrieve a single instance of the class $test = Fruit::singleton(); echo '<br />'; $test->showColor(); // This will issue an E_USER_ERROR. //$test_clone = clone $test; ?>
程序运行结果:
I am constructed My color is !
从这个程序可以看出一些特别的东西。和普通的类不同,单例类是不能直接实例化的,它只能被自身实例化。要获得这种效果,__construct()方法必须被标记为private。如果试图用private构造函数构造一个对象,就会得到一个访问性级别的错误。
那么单例类如何起作用呢?单例类就是要向其它类提供一个实例,用它调用各种方法。单例类回通过内部存储的实例返回一个引用,所以单例类不会重复占用内存和系统资源,从而让应用程序的其它部分更好的使用资源。所以,你的数据库访问最好使用单例模式构建,那么就不会创建太多的数据库连接实例,从而让你的系统跑得更快。
一个空的__clone()方法很有必要,它可以防止对象被复制或者克隆。
self::$instance 可以检测到类是否已经被初始化。如果保存实例的静态成员为空或者还不是类自身的一个实例,那么这个实例将会被创建并保存到存放实例的变量中。
Program List:无private构造函数的单例
一个不严格的单例,没有private构造函数,也没有本身的引用。不知道还算不算模式了。
<?php class Fruit { public static $height = 2; public static $weight = 2; public static function getInstance() { return new Fruit(); } public function getHeight() { return self::$height; } public function getWeight() { return self::$weight; } public function setHeight($value) { if($value > 0 && $value < 100) self::$height = $value; } public function setWeight($value) { if($value > 0 && $value < 100) self::$weight = $value; } public function __toString() { return 'Fruit[height=' . self::$height . ', weight=' . self::$weight . ']'; } } // try to set data before any objects is created Fruit::$height = 55; $msm1 = Fruit::getInstance(); // use the getInstance() method $msm2 = new Fruit(); // use the default constructor $msm2->setWeight(78); // set data with an instantiated object echo $msm1 . '<br />'; echo $msm2 . '<br />'; echo Fruit::getInstance() . '<br>'; echo (new Fruit()); ?>
程序运行结果:
Fruit[height=55, weight=78] Fruit[height=55, weight=78] Fruit[height=55, weight=78] Fruit[height=55, weight=78]
Program List:数据库连接职责
<?php class Database { private $_db; static $_instance; private function __construct() { $this->_db = pg_connect('dbname=example_db'); } private __clone() {}; public static function getInstance() { if( ! (self::$_instance instanceof self) ) { self::$_instance = new self(); } return self::$_instance; } public function query($sql) { return pg_query($this->_db,$sql); } } ?>
如何使用这个单例类?
$db = Database::getInstance(); $db->query('SELECT * FROM example_table');
也就是获取对象的方法有些区别而已,使用起来与其它对象没有特别之处。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

WebStorm Mac版
好用的JavaScript開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3漢化版
中文版,非常好用

Atom編輯器mac版下載
最受歡迎的的開源編輯器