单例模式(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. 8.15 CSS知识点6

    自定义动画 1.animation-name(动画名称) 元素所应用的动画名称,必须与规则@keyframes配合使用,因为动画名称由@keyframes定义. 语法: animation-name ...

  2. MFC 对话框响应OnChar()

    最近在写程序时,出现了对话框里面不接收键盘消息的情况,特别搜索了以下内容 MFC中对话框是不会直接响应OnChar和OnKeyDown消息的,会被 其它控件拦截,测试时发现不会进入这两个函数,必须重定 ...

  3. 开启macbook win7触控屏右键

    开启macbook win7触控屏右键,如下图

  4. 向JSP页面输入信息

    /** * ajax responseTEXT write; * @param request * @param response * @param str */ public static void ...

  5. Windows服务二:测试新建的服务、调试Windows服务

    一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main ...

  6. URLError 异常处理

    3 URLError 首先解释下 URLError 可能产生的原因: 网络无连接,即本机无法上网 连接不到特定的服务器 服务器不存在 在代码中,我们需要用 try-except 语句来包围并捕获相应的 ...

  7. Linux 常用命令 :ls命令

    ls命令是linux下最常用的命令.ls命令就是list的缩写缺省下ls用来打印出当前目录的清单如果ls指定其他目录那么就会显示指定目录里的文件及文件夹清单. 通过ls 命令不仅可以查看linu ...

  8. [原创.数据可视化系列之一]使用openlayers 3 显示聚合数据

    在地图上显示点数据是最常用的地图展示功能之一,但是如果很多点在地图上显示,或造成密密麻麻的一片,无法正常看清楚,这个时候,一般有两种解决方案,一种是根据数据重要程度进行标注,重要的显示大一些,不重要的 ...

  9. error-2015-9-9

    类型的建键部分无效,该键的所有部分均不可为null 映射从第行开始的片段时有问题 表的键具有潜在运行时冲突 列映射到概念端的属性 但是它们未形成entitySet的键属性 报错: 未能加载文件或程序集 ...

  10. 预测帖 苹果在2年之内会换Arm

    这几天看了iPad Pro和新的macbook, 我个人预测,苹果2年之内必换Arm处理器 首先会是笔记本. 而且会把软件移植也做的很好,不需要怎么改代码,只需要编译的时候加入相应的cpu就可以.至于 ...