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

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

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

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

class BookmarkTestCase extends BaseTestCase {
//...
function testUnsetIdIsNull() {
$bookmark = new Bookmark;
$this->assertNull($bookmark->getId());
}
function testIdOnlySetOnce() {
$bookmark = new Bookmark;
$id = 10; //just a random value we picked
$bookmark->setId($id);
$this->assertEqual($id, $bookmark->getId());
$another_id = 20; // another random value, != $id
//state the obvious
$this->assertNotEqual($id, $another_id);
$bookmark->setId($another_id);
// still the old id
$this->assertEqual($id, $bookmark->getId());
}
}
 
应记住一个非常重要的规则:在类中显示定义的方法将会重载由_call()执行的同名方法。你可以专门定义一个同名但行为功能不一样的方法,如setid()来重载任何借助__call()来执行的同名方法。

class Bookmark {
protected $id;
//...
public function setId($id) {
if (!$this->id) {
$this->id = $id;
}
}
}
 

到目前为止, 我们只是有了基本数据对象,让我们增加一些业务逻辑到里面,毕竟,应用数据映射模式的原因之一就是在于将业务逻辑与数据存取分离。为与设计原则保持一致(告知,而不是提问),增加一个fetch()方法来获得实际的(html)书签内容的页面。

以下代码测试了这种能力

class BookmarkTestCase extends BaseTestCase {
//...
function testFetch() {
$bookmark = new Bookmark;
$bookmark->setUrl(‘http://www.google.com/’);
$page = $bookmark->fetch();
$this->assertWantedPattern(
‘~<input[^>]*name=q[^>]*>~im’, $page);
}
}
class Bookmark {
//...
public function fetch() {
return file_get_contents($this->url);
}
}

现在,完整的类如下所示:

class Bookmark {
protected $id;
protected $url;
protected $name;
protected $desc;
protected $group;
protected $crttime;
protected $modtime;
public function setId($id) {
if (!$this->id) {
$this->id = $id;
}
}
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.’()’);
}
}
protected function validateAttribute($name) {
if (in_array(strtolower($name),
array_keys(get_class_vars(get_class($this))))) {
return strtolower($name);
}
}
public function fetch() {
return file_get_contents($this->url);
}
}

拥有了Bookmark类后,我们来看下BookmarkMapper 类。BookmarkMapper 类核心的工作是从数据库取出数据并创建Bookmark类。

首先,我们为了实现BookmarkMapper,需要增加新的数据库记录。

在数据映射模式里面,域对象是对数据映射是透明的,但是它包含了所有的商业逻辑和创建对象潜在的规则。其中一个创建数据记录规则就是创建一个新的Bookmark对象实例,设置属性,还有让BookmarkMapper来保存新创建的对象实例。好,现在我们来看下如何实现这个接口。

BookmarkMapper 必须能够与数据库进行交互。就像在前面两个章节中所说的一样,我们使用

ADOdb 来访问数据库。此外,在构造BookmarkMapper的时候,把ADOdb的连接传递过去。

//代码
class BookmarkMapper {
protected $conn;
public function __construct($conn) {
$this->conn = $conn;
}
}

BookmarkMapper 还必须导入刚才提到的XML 文件。为了让XML更方便使用,我们把映射存储为一些类的名字=> simplexml 元素。我们把这个加在构造函数里面:

class BookmarkMapper {
protected $map = array();
protected $conn;
public function __construct($conn) {
$this->conn = $conn;
foreach(simplexml_load_file(‘bookmark.xml’) as $field) {
$this->map[(string)$field->name] = $field;
}
}
}

现在你可以创建一个测试来测试save() 方法。

class BookmarkMapperTestCase extends BaseTestCase {
function testSave() {
$bookmark = new Bookmark;
$bookmark->setUrl(‘http://phparch.com/’);
$bookmark->setName(‘php|architect’);
$bookmark->setDesc(‘php|arch magazine homepage’);
$bookmark->setGroup(‘php’);
$this->assertNull($bookmark->getId());
$mapper = new BookmarkMapper($this->conn);
$mapper->save($bookmark);
$this->assertEqual(1, $bookmark->getId());
// a row was added to the database table
$this->assertEqual(1, $this->conn->getOne(
‘select count(1) from bookmark’));


}
}

这里,测试代码创建了一个新的Bookmark 类的实例,并设置了该类的相对应的属性,然后让一个BookmarkMapper 实例来存储(save())这个Bookmark实例。另外,这个测试还测试存储对象、设置ID、往数据库插入行的有效性。


延伸阅读:
从魔兽看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号