单例模式(Singleton Pattern 单件模式或单元素模式)

单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式是一种常见的设计模式,在计算机系统中,线程池、缓存、日志对象、对话框、打印机、数据库操作、显卡的驱动程序常被设计成单例。

单例模式分3种:懒汉式单例、饿汉式单例、登记式单例。

单例模式有以下3个特点:

1.只能有一个实例。

2.必须自行创建这个实例。

3.必须给其他对象提供这一实例。

那么为什么要使用PHP单例模式?

PHP一个主要应用场合就是应用程序与数据库打交道的场景,在一个应用中会存在大量的数据库操作,针对数据库句柄连接数据库的行为,使用单例模式可以避免大量的new操作。因为每一次new操作都会消耗系统和内存的资源。

在以往的项目开发中,没使用单例模式前的情况如下:

------------------------------------------------------------------------------------------------------------------------

//初始化一个数据库句柄
$db = new DB(...);
//比如有个应用场景是添加一条用户信息
$db->addUserInfo();
......
//然而我们要在另一地方使用这个用户信息,这时要用到数据库句柄资源,可能会这么做
......
function test() {
   $db = new DB(...);
   $db->getUserInfo();
......
有些朋友也许会说,可以直接使用global关键字!
   global $db;
......

------------------------------------------------------------------------------------------------------------------------

的确global可以解决问题,也起到单例模式的作用,但在OOP中,我们拒绝这种编码。因为global存在安全隐患(全局变量不受保护的本质)。

全局变量是面向对象程序员遇到的引发BUG的主要原因之一。这是因为全局变量将类捆绑于特定的环境,破坏了封装。如果新的应用程序无法保证一开始就定义了相同的全局变量,那么一个依赖于全局变量的类就无法从一个应用程序中提取出来并应用到新应用程序中。

确切的讲,单例模式恰恰是对全局变量的一种改进,避免那些存储唯一实例的全局变量污染命名空间。你无法用错误类型的数据覆写一个单例。这种保护在不支持命名空间的PHP版本里尤其重要。因为在PHP中命名冲突会在编译时被捕获,并使脚本停止运行。

PHP单例模式实例:

先看图:

上面的对象图中,有一个“单例对象”,而“客户甲”、“客户乙”和“客户丙”是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。

<?php

class User {
//静态变量保存全局实例
private static $_instance = null;
//私有构造函数,防止外界实例化对象
private function __construct() {
}
//私有克隆函数,防止外界克隆对象
private function __clone() {
}
//静态方法,单例统一访问入口
static public function getInstance() {
if (empty(self::$_instance)) {
self::$_instance = new self (); //or self::$_instance = new User();
}
return self::$_instance;
}
public function getName() {
echo 'hello world!';
}
} ?> 单例模式 连接mysql数据库
<?php

  class DB {
       //单例模式 连接数据库
      private static $_instance = null;
      private static $conn = null;
      private function __construct($host, $name, $pwd, $databasename){
          self::$conn = mysql_connect($host, $name, $pwd);
          mysql_select_db($databasename, self::$conn);
      }
      private function __clone(){ }
      public function get_instance($host, $name, $pwd, $databasename){
              if(empty(self::$_instance)){
               self::$_instance = new self($host, $name, $pwd, $databasename);
             }
        return self::$_instance;
      }
  }

?>

单例模式的优缺点:

优点:

1. 改进系统的设计

2. 是对全局变量的一种改进

缺点:

1. 难于调试

2. 隐藏的依赖关系

3. 无法用错误类型的数据覆写一个单例

php设计模式--单例模式的更多相关文章

  1. 设计模式 单例模式(Singleton) [ 转载2 ]

    设计模式 单例模式(Singleton) [ 转载2 ] @author java_my_life 单例模式的结构 单例模式的特点: 单例类只能有一个实例. 单例类必须自己创建自己的唯一实例. 单例类 ...

  2. 设计模式 单例模式(Singleton) [ 转载 ]

    设计模式 单例模式(Singleton) [ 转载 ] 转载请注明出处:http://cantellow.iteye.com/blog/838473 前言 懒汉:调用时才创建对象 饿汉:类初始化时就创 ...

  3. c#设计模式-单例模式(面试题)

    c#设计模式-单例模式 单例模式三种写法: 第一种最简单,但没有考虑线程安全,在多线程时可能会出问题, public class Singleton { private static Singleto ...

  4. java设计模式单例模式 ----懒汉式与饿汉式的区别

    常用的五种单例模式实现方式 ——主要: 1.饿汉式(线程安全,调用率高,但是,不能延迟加载.) 2.懒汉式(线程安全,调用效率不高,可以延时加载.) ——其他: 1.双重检测锁式(由于JVM底层内部模 ...

  5. 最简单的设计模式——单例模式的演进和推荐写法(Java 版)

    前言 如下是之前总结的 C++ 版的:软件开发常用设计模式—单例模式总结(c++版),对比发现 Java 实现的单例模式和 C++ 的在线程安全上还是有些区别的. 概念不多说,没意思,我自己总结就是: ...

  6. ES6教程-字符串,函数的参数,了解函数的arguments对象,js面向对象,设计模式-单例模式,解构赋值

    前言 主要讲解了ES6对字符串的拓展,包括includes,startsWith和endsWith,另外增加了字符串模板. Start includes()是否包含 startsWith()以什么开头 ...

  7. Java设计模式の单例模式

    -------------------------------------------------- 目录 1.定义 2.常见的集中单例实现 a.饿汉式,线程安全 但效率比较低 b.单例模式的实现:饱 ...

  8. java设计模式——单例模式(一)

    一. 定义与类型 定义:保证一个类仅有一个实例,并提供一个全局访问点 类型:创建型 二. 适用场景 想确保任何情况下都绝对只用一个实例 三. 优缺点 优点: 在内存里只有一个实例,减少了内存开销 可以 ...

  9. php实现设计模式————单例模式

    php实现设计模式————单例模式 什么是单例模式 为什么要使用单例模式 php中有哪些方式实现新建一个对象实例 如何阻止这种实例化实现理想的单例模式 代码实现 什么是单例模式 为什么要使用单例模式 ...

  10. JAVA设计模式-单例模式(Singleton)线程安全与效率

    一,前言 单例模式详细大家都已经非常熟悉了,在文章单例模式的八种写法比较中,对单例模式的概念以及使用场景都做了很不错的说明.请在阅读本文之前,阅读一下这篇文章,因为本文就是按照这篇文章中的八种单例模式 ...

随机推荐

  1. Tomcat和JavaWeb笔记

    <iframe src="http://www.xmind.net/embed/XFXh" width="900px" height="540p ...

  2. 线程操作UI界面的方法

    以前一般都是用BeginInvoke来刷新UI界面,现在采用 SynchronizationContext 来刷新,写起来清楚多了. SynchronizationContext synchroniz ...

  3. SecureCRT的安装

    SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件. SecureCRT 是高度可定制的终端仿真器,适用于 In ...

  4. Canvas画图在360浏览器中跑偏的问题

    问题描述,canvas画图的js代码中编写的是画正方形的代码,结果在360浏览器上变成了长方形,不知道怎么回事,请问各位大神是否遇到过此类问题? <!DOCTYPE html> <h ...

  5. 如何用Eclipse进行单元测试

    1.在个人电脑中安装一个集成开发环境(Microsoft Visual Studio.Eclipse或其它工具均可),要求该环境能够提供单元自动测试功能: 2.记录安装过程,并将全部内容发表在博客中: ...

  6. C#删除datable空行

    //去除dataTable空行 public DataTable RemoveEmpty(DataTable dt) { List<DataRow> removelist = new Li ...

  7. php中$row=mysql_fetch_row()出错问题

    在写php时用到这样一个问题,代码如下: $sql="select * from sina"; mysql_connect("localhost"," ...

  8. NodeJS搭建HTTPS服务器

    [NodeJS搭建HTTPS服务器] http://cnodejs.org/topic/54745ac22804a0997d38b32d

  9. Java 对文件的读取操作

    package pack; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; ...

  10. Python Microsoft Visual C++ Compiler Package for Python 2.7

    错误描述: 在从源代码安装Python模块时遇到此错误.可是我明明从官网下载并安装了Microsoft Visual C++ Compiler Package for Python 2.7,且配置了环 ...