您的位置:首页 > 编程语言 > PHP开发

PHP中的实现Registry模式过程中的领悟

2007-05-06 13:23 676 查看
PHP注册模式用于存储一些公共资源,比如数据库连接,全局对象,通常Registry实现为一个单件模式,它本身就是一个单件.我在编写Registry对象的时候犯了一个错误,就是在实现set方法的时候没有pass by reference,所有没有通过simpletest的test case.睡了一觉,第二天脑子似乎清醒了一些.发现在实现set的时候没有通过 & 传递对象.下面是我没有通过test case的Registry实现代码:

<?php
/*
Singleton && Registry Design Pattern Implementation
*/

class Registry {
private $_store = array();
public function getInstance() {
static $instance = array();
if (!$instance) {
$instance[0] = new Registry;
}
return $instance[0];
}
public function &get($key){
if($this->isValid($key)){
return $this->_store[$key];
}
}
public function set($key, $object){
$this->_store[$key] = &$object;
}
public function isValid($key){
return array_key_exists($key,$this->_store);
}
}
?>

Test Case:


<?php


require_once 'simpletest/unit_tester.php';


require_once 'simpletest/reporter.php';


require_once 'Registry.php';


class RegistryTestCase extends UnitTestCase{


function testRegistryIsSingleton(){


$this->assertIsA($reg = Registry::getInstance(), 'Registry');


$this->assertReference($reg, Registry::getInstance());


}



function testEmptyRegistryKeyIsReturnNull(){


$reg = Registry::getInstance();


$this->assertNull($reg->get('key'));


}



function testEmptyRegistryKeyIsInvalid(){


$reg = Registry::getInstance();


$this->assertFalse($reg->get('key'));


}



function testSetRegistryKeyBecomesValid(){


$reg = Registry::getInstance();


$test_value = 'something';


settype($test_value, 'Object');


$reg->set('key', $test_value);


$this->assertTrue($reg->isValid('key'));


}



function testRegistryValueIsReference(){


$reg = Registry::getInstance();


$test_value = 'something';


$reg->set('key', $test_value);


$this->assertReference($test_value, $reg->get('key'));


$test_value .= ' else';


$reg->set('key', $test_value);


$this->assertEqual('something else', $reg->get('key'));


}


}


if(!defined('RUN_ALL')){


$test = new RegistryTestCase ();


$test->run(new HtmlReporter());


//$test->run(new TextReporter());


}


?>

仅仅是缺少一个" &",这就是问题所在^_^,神奇,All Pass,Green Bar,HoHo:

<?php
/*
Singleton && Registry Design Pattern Implementation
*/

class Registry {
private $_store = array();
public function getInstance() {
static $instance = array();
if (!$instance) {
$instance[0] = new Registry;
}
return $instance[0];
}
public function &get($key){
if($this->isValid($key)){
return $this->_store[$key];
}
}
public function set($key, &$object){
$this->_store[$key] = &$object;
}
public function isValid($key){
return array_key_exists($key,$this->_store);
}
}
?>

使用实例: 数据库连接注册库单件

<?php
require_once 'DB.php';
require_once 'simpletest/unit_tester.php';
require_once 'simpletest/reporter.php';
class DatabaseConnectionSingleton {
public static function getInstance() {
/* 这里$db对象是静态的,对getInstance()的多次调用返回相同的引用,通过下面的TestCase得到了验证 */
static $db = null;
if ($db === null) {
$db = new DatabaseConnectionSingleton();
}
return $db;
}
private $_handle = null;
# 构造方法是私有的,所以不能直接使用 new 关键字实例化,这点对于单件模式至关重要
private function __construct() {
$dsn = 'mysql://root:root@localhost/test';
$this->_handle = DB :: connect($dsn, array ());
}
public function handle() {
return $this->_handle;
}
}
# debug output
#print( "Handle = ".DatabaseConnectionSingleton::getInstance()->handle()." " );
#print( "Handle = ".DatabaseConnectionSingleton::getInstance()->handle()." " );
# dump DatabaseConnectionSingleton 对象
#var_dump(DatabaseConnectionSingleton::getInstance());
#print_r(get_included_files());
/**
* 验证对getInstance()的多次调用返回相同的引用.
*/
class DatabaseConnectionSingletonTestCase extends UnitTestCase {
function testIsReferceReturnsObjectTwice() {
$instance1 = DatabaseConnectionSingleton :: getInstance();
$instance2 = DatabaseConnectionSingleton :: getInstance();
$this->assertReference($instance1, $instance2);
}
}
$test = new DatabaseConnectionSingletonTestCase();
$test->run(new HtmlReporter());

# 下面是单件模式的原型,注意三个要点,
# 1. 对象必须是私有成员.
# 2.私有的构造函数
# 3. 一个公共的实例化并返回该Singleton的可被外部对象调用的成员函数
# 单件模式的事例化过程被从外部移到了内部.只有通过内部方法才能实例化对象
class Singleton {
private static $instance = null;
private function __construct() {
}
public static function getInstance() {
if (self :: $instance === null) {
self :: $instance = new Singleton();
}
return self :: instance;
}
}
?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: