PHP程序员站--PHP编程开发平台
 当前位置:主页 >> PHP高级编程 >> 高级应用 >> 

PHP设计模式介绍 第十六章 数据映射模式

PHP设计模式介绍 第十六章 数据映射模式

来源:互联网  作者:  发布时间:2010-05-22
前两章――动态数据模式与表数据网关模式各自展示对记录与每个

让我们从设置与获取Bookmark类的’url’属性的代码开始。

class Bookmark {
protected $url;
// ...
public function getUrl() {
return $this->url;
}
public function setUrl($url) {
$this->url = $url;
}
}

你能通过反射机制来避免的单调的编写无数简单的getter和setter方法。通过对对象自身的“窥探”,你能使对象测试某个特定的属性是否具有getters和setters以及是否这样命名的。

让我们来一些测试。

class BookmarkTestCase extends BaseTestCase {
//...
function testAccessorsAndMutators() {
$bookmark = new Bookmark(false);
$props = array(‘Url’, ‘Name’, ‘Desc’,
‘Group’, ‘CrtTime’, ‘ModTime’);
foreach($props as $prop) {
$getprop = “get$prop”;
$setprop = “set$prop”;
$this->assertNull($bookmark->$getprop());
$val1 = ‘some_val’;
$bookmark->$setprop($val1);
$this->assertEqual($val1,
$bookmark->$getprop());
$val2 = ‘other_val’;
$bookmark->$setprop($val2);
$this->assertNotEqual($val1,
$bookmark->$getprop());
$this->assertEqual($val2,
$bookmark->$getprop());
}
}
}

 
对每一个书签的属性,测试都通过mutaror方法设定了一个值,并与通过accessor方法返回的值进行校验。值再次被改变并校验。

这段代码代码基于常例而不是某种直接的映射。获取与变更方法的名称由get与set开头,并由属性名组成(小写)。例如,获取’url’方法的名称为getUrl(),修改url方法的名称则为setUrl()。

这里是实现动态获取与修改方法的一些代码示例。

class Bookmark {
protected $url;
protected $name;
protected $desc;
protected $group;
protected $crttime;
protected $modtime;
//...
public function __call($name, $args) {
if (preg_match(‘/^(get|set)(\w+)/’, strtolower($name), $match)
&& $attribute = $this->validateAttribute($match[2])) {
if (‘get’ == $match[1]) {
return $this->$attribute;
} else {
$this->$attribute = $args[0];
}
}
}
protected function validateAttribute($name) {
if (in_array(strtolower($name),
array_keys(get_class_vars(get_class($this))))) {


return strtolower($name);
}
}
}

这段代码基于PHP5的魔术方法__call(),当调用未定义(未在类中明确定义)的实例方法时__call()方法被调用。方法(无定义)的名称作为第一个参数传给__call(),而方法本身所需的参数作为__call方法的第二参数以数组的形式被传入。

要达到动态生成getter 和setter方法,则方法名被分析,看是否是以’get’或是’set’开头,并且是否以一个正确的对象属性名结束。如果是这样,属性值就能正确的修改与返回。这个动态方法就可以代替手工实现的geturl()与geturl()方法了,这样,这些手工代码就可以删除了。

这儿有一个副作用要注意,如果用本代码调用了别的方法,则不会有错误信息给出。为了防止这种情况,让我们对错误的调用抛出一个例外出理。

class Bookmark {
//...
public function __call($name, $args) {
if (preg_match(‘/^(get|set)(\w+)/’, strtolower($name), $match)
&& $attribute = $this->validateAttribute($match[2])) {
if (‘get’ == $match[1]) {
return $this->$attribute;
} else {
$this->$attribute = $args[0];
}
} else {
throw new Exception(
‘Call to undefined method Bookmark::’.$name.’()’);
}
}
}

你能通过以下代码测试上述例外代码

class BookmarkTestCase extends BaseTestCase {
//...
function testBadGetSetExceptions() {
$mapper = new BookmarkMapper($this->conn);
$this->addSeveralBookmarks($mapper);
$bookmark = $mapper->findById(1);
try {
$this->assertNull($bookmark->getFoo());
$this->fail(‘no exception thrown’);
}
catch (Exception $e) {
$this->assertWantedPattern(‘/undefined.*getfoo/i’,
$e->getMessage());
}
try {
$this->assertNull($bookmark->setFoo(‘bar’));
$this->fail(‘no exception thrown’);
}
catch (Exception $e) {


$this->assertWantedPattern(‘/undefined.*setfoo/i’,
$e->getMessage());
}
}
}

这儿还有另一个要注意的事项:一但当$id属性设置好后就不能变动它,让我们建立一个试验来说明上述事项。调用一次SetId()来设置ID值后,就可以用getid()反复获取其值,但随后再次调用setid()就应该无效。


延伸阅读:
从魔兽看PHP设计模式
《PHP设计模式介绍》导言
PHP设计模式介绍 第一章 编程惯用法
PHP设计模式介绍 第二章 值对象模式
PHP设计模式介绍 第三章 工厂模式
PHP设计模式介绍 第四章 单件模式
PHP设计模式介绍 第五章 注册模式
PHP设计模式介绍 第六章 伪对象模式
PHP设计模式介绍 第七章 策略模式
PHP设计模式介绍 第八章 迭代器模式


PHP设计模式介绍 第九章 观测模式
PHP设计模式介绍 第十章 规范模式
PHP设计模式介绍 第十一章 代理模式
PHP设计模式介绍 第十二章 装饰器模式
PHP设计模式介绍 第十三章 适配器模式
PHP设计模式介绍 第十四章 动态记录模式
PHP设计模式介绍 第十五章 表数据网关模式
最新文章
推荐阅读
月点击排行榜
PHP程序员站 Copyright © 2007-2010,PHPERZ.COM All Rights Reserved 粤ICP备07503606号