本方法中的神奇之处在于$this->_store =& $GLOBALS [REGISTRY_GLOBAL_STORE;] 这一行,引用操作符将全局数组绑定到实例变量$_store上。这是单件模式 实现的关键所在:每次在对象中使用$this->_store变量时,作用反映到全局变量中。
但是并 不推荐基于全局变量的解决方案。如果PHP4支持这一特性的话,静态类变量会是更好的解决方案。然而 ,我们可以在代码中通过引用实现静态类变量吗?
测试与 RegistryGlobal 类的测试相似。
代码:
class RegistryMonoStatePHP4TestCase extends UnitTestCase {
function testRegistryMonoState() {
$this->assertCopy(
$reg =& new RegistryMonoState;
$reg2 =& new RegistryMonoState);
$this->assertFalse ($reg->isValid(‘key’));
$this->assertNull($reg->get (‘key’));
$test_value = ‘something’;
$reg->set (‘key’, $test_value);
$this->assertReference($reg->get (‘key’), $reg2->get(‘key’));
}
}
要自己 实现类静态变量,可以将一个对函数静态变量的引用绑定到类的实例变量上。
代码:
class RegistryMonoState {var $_store;
function &_initRegistry() { static $store = array(); return $store;
}
function RegistryMonoState() {
$this->_store =& $this->_initRegistry();
}
function isValid($key) {
return array_key_exists($key, $this->_store);
}
function &get ($key) {
if (array_key_exists($key, $this->_store))
return $this- >_store[$key];
}
function set($key, &$obj) {
$this->_store [$key] =& $obj;
}
}
initRegistry()方法包含一个初始化为数组的静 态变量。这个静态变量通过引用返回。在构造函数中$_store实例变量被赋于通过initRegistry()函数返 回的引用——即静态数组。好!一个PHP4的类静态变量产生了。
使用类静态变量的实 现:
PHP5中,没有必要自己实现类静态变量,因为PHP5直接支持类静态变量。因此,PHP5简化了 实现。而且,PHP5中引用、对象不再有PHP4中的意义,但是assertReference() 处理了这种差别,如果 两个变量指向同一个对象句柄也可以通过测试。
以下是为PHP5改写的类似的ReGIStry测试用例。
代码:
// PHP5
class RegistryMonoStatePHP5TestCase extends UnitTestCase {
function testRegistryMonoState() {
$this->assertCopy(
$reg = new RegistryMonoState
,$reg2 = new RegistryMonoState);
$this- >assertFalse($reg->isValid(‘key’));
$this->assertNull($reg- >get(‘key’));
$test_value = new TestObj;
$reg->set (‘key’, $test_value);
$this->assertReference($test_value, $reg2- >get(‘key’));
}
}
以下是PHP5版本的使用静态类变量的 Registry类。
代码:
class RegistryMonoState {
protected static $store = array();
function isValid($key) {
return array_key_exists($key, RegistryMonoState::$store);
}
function get($key) {
if (array_key_exists ($key, RegistryMonoState::$store))
return RegistryMonoState::$store[$key];
}
function set($key, $obj) {
RegistryMonoState::$store[$key] = $obj;
}
}
PHP5中用这种方式编码Registry类的一个有趣的效果是你可以用相同的代码使用实例 或者静态方法。以下是证明仅仅使用静态方法的测试用例。
代码:
class RegistryMonoStatePHP5TestCase extends UnitTestCase {
function testRegistryMonoState() { /*...*/ }
function testRegistryMonoStateStaticCalls() {
$this->assertFalse(RegistryMonoState::isValid(‘key’));
$this- >assertNull(RegistryMonoState::get(‘key’));
$test_value = new TestObj; RegistryMonoState::set(‘key’, $test_value);
$this- >assertIdentical($test_value, RegistryMonoState::get(‘key’));
}
(编辑:)