php 单例模式应用-改进版
来源:互联网 发布:js settimeout原理 编辑:程序博客网 时间:2024/06/02 03:39
单例模式的应用
作者:Wucl
时间:2014-11-11
章节内容:基础准备、实现方式、个人心得。
1. 基础准备:
单例顾名思义单一实例,即一次程序执行过程中一个类只有一个相同特性的实例。为了实现这个目的:首先,需要一个静态的变量存放一个类的相同特性实例,以便下次需要时直接从静态变量中取出并使用。其次,需要防止类被克隆。最后,实现实例类和如何存放相同特性的实例。
2. 实现方式(完整的方式见附录):
首先,创建单例核心类:class Singleton{}
其次,声明静态变量和防克隆method:
private static $instances = array();
final private function __clone() {}
然后,实现单例化method,其中我选择使用数组键值对的方式存放实例。考虑到不同参数实例类时,产生的实例对象不相同:键=类名+字符串化参数、值=实例对象。
1) 字符串化参数的method如下:
private static function arrToStr($params = array()){
$str = '';
foreach ($params as $v=>$val){
if(is_array($val) || is_object($val)){
$val = is_object($val) ? get_object_vars($val) : $val;
$str .= 'array('.self::arrToStr($val).')';
}else{
$str .= $val.'_';
}
}
return trim($str, '_');
}
使用方式:
$class_name = get_called_class();
$instances_name = $class_name;
if(!empty(func_get_args())){
$instances_name .= '_'.self::arrToStr(func_get_args());
}
2) 单例化主体类的method如下:
final public static function instance(){
$class_name = get_called_class();
$instances_name = $class_name;
if(!empty(func_get_args())){
$instances_name .= '_'.self::arrToStr(func_get_args());
}
if (!isset(self::$instances[$instances_name]) || !(self::$instances[$instances_name] instanceof $class_name))
self::$instances[$instances_name] = self::singletonInstance($class_name, func_get_args());
return self::$instances[$instances_name];
}
3) 多参数单例化类的method如下(只提供了10个参数以下的实例):
private static function singletonInstance($class_name='', $params=array())
{
$num = count($params);
switch($num) {
case 1:
$instance = new $class_name($params[0]);
break;
case 2:
$instance = new $class_name($params[0], $params[1]);
break;
case 3:
$instance = new $class_name($params[0], $params[1], $params[2]);
break;
case 4:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3]);
break;
case 5:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4]);
break;
case 6:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5]);
break;
case 7:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6]);
break;
case 8:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7]);
break;
case 9:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7], $params[8]);
break;
case 10:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7], $params[8], $params[9]);
break;
default:
$instance = new $class_name();
break;
}
return $instance;
}
4) 这是一个单例方式使用的例子:
class Db extends Singleton{
public function __construct($db = array(), $db2 = array()){}
public static function getInstance($db = array(), $db2 = array()){
return self::instance($db, $db2);
}
}
3. 个人心得:
我曾经做过一个测试,结果如下:
142600
142600
142600
144712
144768
144824
前3行数字为使用单例所占内存,使用3次对象时所占内存的大小一样,
后3行数字为正常实例所占内存,使用3次对象时所占内存会逐次变大。
上述结果表明使用单例模式是有必要的,当然开始的时候我并没有考虑到不同参数的情况,以至于不同参数使用单例核心类实例出来的类,都是第一次实例的类,后面才使用func_get_args()实现了不同参数实例不同的类。这就表明我们所做每一件事,都需要一步一步的实验才能把这件事做得更好。
4. 附录(以下是完整的单例核心类,希望能帮到以后的自己和看这份文档的):
<?php
/**
*@desc: 单例模式的实现类
*@author: Wucl
*@since: 2014-09-10
*/
namespace Library\Core;
class Singleton{
private static $instances = array();
/**
*私有化__clone()方法
*/
final private function __clone() {}
/**
* 单例化类
* @return 返回实例类
*/
final public static function instance(){
$class_name = get_called_class();
$instances_name = $class_name;
if(!empty(func_get_args())){
$instances_name .= '_'.self::arrToStr(func_get_args());
}
if (!isset(self::$instances[$instances_name]) || !(self::$instances[$instances_name] instanceof $class_name))
self::$instances[$instances_name] = self::singletonInstance($class_name, func_get_args());
return self::$instances[$instances_name];
}
/**
* 多维数组和对象转换成字符串
* @param unknown $params 参数数组
* @return string
*/
private static function arrToStr($params = array()){
$str = '';
foreach ($params as $v=>$val){
if(is_array($val) || is_object($val)){
$val = is_object($val) ? get_object_vars($val) : $val;//对象先转换为数组
$str .= 'array('.self::arrToStr($val).')';
}else{
$str .= $val.'_';
}
}
return trim($str, '_');
}
/**
* 多参数实例
* @param unknown $class_name
* @param unknown $params
*/
private static function singletonInstance($class_name='', $params=array()){
$num = count($params);
switch($num) {
case 1:
$instance = new $class_name($params[0]);
break;
case 2:
$instance = new $class_name($params[0], $params[1]);
break;
case 3:
$instance = new $class_name($params[0], $params[1], $params[2]);
break;
case 4:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3]);
break;
case 5:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4]);
break;
case 6:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5]);
break;
case 7:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6]);
break;
case 8:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7]);
break;
case 9:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7], $params[8]);
break;
case 10:
$instance = new $class_name($params[0], $params[1], $params[2], $params[3], $params[4], $params[5], $params[6], $params[7], $params[8], $params[9]);
break;
default:
$instance = new $class_name();
break;
}
return $instance;
}
}
?>
- php 单例模式应用-改进版
- 单例模式--改进版
- 单例模式(改进版)【转】
- 单例模式的改进
- PHP单例模式及应用实例
- php应用数据库连接中的单例模式
- PHP单例模式应用详解
- php在设计模式中的应用之单例模式
- php 单例模式下 数据库链接的应用
- PHP单例模式在MVC框架设计中的应用
- PHP单例模式在MVC框架设计中的应用 (
- 配置文件读取类conf.class.php 单例模式应用
- php单例模式的常见应用场景
- php单例模式
- php单例模式
- PHP单例模式
- PHP单例模式
- PHP单例模式
- cocos2dx3.0之读取cocostudio的UI控件
- Quartz 概要学习笔记
- 《c程序设计语言》读书笔记-3.5-按要求进制位数字转字符串
- android 带你从源码分析LayoutInflater工作原理
- switch老化时间过长导致主机不通解决一例
- php 单例模式应用-改进版
- 动态内存分配
- python中字典的常用方法
- 日常问题笔记
- CMake入门指南
- poj 2508 Conic distance 计算几何
- 添加元素 下标操作
- js控制图片的缩放代码示例
- leetcode_题解_min stack