php教程:php设计模式介绍之注册模式(3)
测试又通过了!现在我们想最终特性进发:给定一个属性key,注册模式类的get()方法将返回一个对特定对象的引用。一下为符合这一要求的测试用例。
代码:
class RegistryPHP4TestCase extends UnitTestCase
{function testRegistryIsSingleton() { /*...*/ }
function testEmptyRegistryKeyIsInvalid() { /*...*/ }
function testEmptyRegistryKeyReturnsNull() { /*...*/ }
function testSetRegistryKeyBecomesValid() { /*...*/ }
function testSetRegistryValueIsReference()
{$reg =& Registry::getInstance();$test_value = 'something';
$reg->set('key', $test_value);
$this->assertReference($test_value, $reg->get('key'));
//another way to test the reference
$test_value .= ' else';
$this->assertEquual('something else',$reg->get('key'));
}
}
以下为注册模式类的完整实现代码。
代码:
class Registry
{var $_store = array();
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;}
function &getInstance()
{static $instance = array();
if (!$instance) $instance[0] =& new Registry;
return $instance[0];
}
}
“注册模式”的get()方法会返回一个对象引用。类似的,set()方法的$obj参数要求得到一个对象引用并被赋值$this->_store[$key].。get()和set()方法的联合恰当使用能够满足assertReference()测试。
作者注:
“注册模式”的get()Registry::get()方法的代码应该写成@$this->_store[$key;]的形式,但是最好避免使用错误抑制符,使用错误抑制符的代码会变的摸棱两可,你需要花费额外的时间去了解你是否会再次访问这段代码。array_key_exists()方法指出了应该避免的错误。
PHP5中,对象句柄(引用)带来了革命性的变化——你可以从对象引用的困境中解脱出来。事实上PHP5中注册模式的实现变的简单多了。因为你再也不用担心因为没有通过引用传递对象而引起致命错误的情况下使用联合数组。在PHP5中,你甚至能在注册模式中混和使用对象和变量。