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;
}
}
?>
<?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;
}
}
?>
相关文章推荐
- PHP中的实现Registry模式过程中的领悟
- PHP下用B/S编程模式去实现C/S软件编程模式下的插件引擎功能!
- 设计模式- 使用抽象工厂实现多数据库切换实现过程
- php实现工厂模式
- Windows下用mysql+apache+php实现论坛的基本过程 推荐
- php中实现3DES算法(ECB加密模式PKCS5Padding填充)
- PHP 观察者模式 的真正实现
- [设计模式]head first 设计模式之PHP实现 第一章
- php 反射机制实现代理模式
- [转]利用 PHP 的 SPL 快速实现 Observer 设计模式
- [设计模式]head first 设计模式之PHP实现 第三章 装饰者模式
- PHP和golang实现设计模式-抽象工厂模式
- php实现单例模式原理
- 设计模式- 使用抽象工厂实现多数据库切换实现过程
- php glob()函数实现目录文件遍历与寻找与模式匹配的文件路径
- 设计模式-观察者模式(PHP实现)
- 设计模式的PHP实现示例(转)
- 利用php给图片添加文字水印--面向对象与面向过程俩种方法的实现
- 每日一记之php单例模式实现
- PHP使用微信开发模式实现搜索已发送图文及匹配关键字回复的方法