搜索
首页php教程php手册PHP职责模式单例模式

模式对于面向对象开发是相当重要的。一种模式可以帮助我们创建能够实现特定任务的对象,成为类的职责。模式还允许我们修改某个类,但不需要修改与这个类有关系的代码,这个称为类的多态。

单例模式又称为职责模式,它用来在应用程序中创建一个单一的功能访问点。下面我们来探讨并且结结实实地掌握单例的思想还有应用。

在复杂的系统中,使用单例模式在维持应用程序状态的同步方面尤其有用。所有的单例类至少拥有以下三个元素:

  • 一个标记为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');

也就是获取对象的方法有些区别而已,使用起来与其它对象没有特别之处。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器