ADOdb默认返回的是行记录的散列数组,我有意让这个例子稍微复杂一点,来强制其返回一个数据转输对象,这样代码就有意思多了。并且你将看到这个示例应用了前面学习过的一些设计模式)。
以下测试用例是上述需求的简化表述。
class TableDataGatewayTestCase extends BaseTestCase { |
class BookmarkGateway{ // ... public function findByTag($tag) { $rs = $this->conn->execute( ‘select * from bookmark where tag like ?’ ,array($tag.’%’)); return new AdoResultSetIteratorDecorator($rs); } } |
很典型的,findByTag()首先调用execute()方法生成一个数据集。ADOdb的execute()方法带入两个参数,待执行的SQL语句和一个可选的梆定参数变量的数组。因为findByTag()需要用带通配符的LIKE操作,并且ADOdb会自动的给查询字串加引号,所以必须要给作为参数的数组在其内部就加上通配符。Execute()产生一个记录集后,AdoResultSetIteratorDecorator()将对其进行封包。AdoResultSetIteratorDecorator()的主要目的在于把结果集“转换”为可迭代的对象集合,也因此而得名。
ADOdb通过包含adodb-iterator.inc.php提供对迭代的支持。其中定义了一个ADODB_Iterator的类,其实质是将ADOResultSet修饰成为PHP5的一个迭代接口标准库。这使得你可以快速的形成一个可以遍历的结果集了。然而,迭代器的默认行为还是返回一个聚合数组。正如你将在下述试验中看到的那样。
class AdoResultSetIteratorDecoratorTestCase extends BaseTestCase { function testADOdbDecorator() { $gateway = new BookmarkGateway($this->conn); $this->addSeveralBookmarks($gateway); $rs = $this->conn->execute(‘select * from bookmark’); foreach($rs as $row) { $this->assertIsA($row, ‘array’); $this->assertIsA($rs->fetchObj(), ‘ADOFetchObj’); } } } |
这儿,通过ADOdb迭代器,表数据就可以被建立,存储,迭代获取数据。
突出显示的代码行实际是无效,要注意避免。你的确能为每一行生成一个对象,如果这样,你就不得不在你的应用中到处重复这个笨拙的代码来实现对整个集合的迭代。
一个更好的解决方案――能更直接的满足对象集合迭代要求的是:修饰ADOdb迭代器。
测试外部库
写一个小测试用例来帮助你探测第三方库,更好的了解它们的特点。一系列的测试用例也能使你更好的把握住对外部库的依赖性(独立性),或是你的代码是如何特定的使用这些库,这样当库因升级而改变时能更快的找到并解决问题。
如果你担心对这些外部库的依赖性,则引入适配器(见第十三章--适配器模式)使你的代码从这种依赖关系中独立出来。
让我们写一个测试用例来演示迭代器是如何工作的。
class AdoResultSetIteratorDecoratorTestCase extends BaseTestCase { // ... function testRsDecorator() { $gateway = new BookmarkGateway($this->conn); $this->addSeveralBookmarks($gateway); $rs = $this->conn->execute(‘select * from bookmark’); $count=0; foreach(new AdoResultSetIteratorDecorator($rs) as $bookmark) { ++$count; $this->assertIsA($bookmark, ‘ADOFetchObj’); $this->assertTrue($bookmark->id > 0); $this->assertTrue(strlen($bookmark->url) > 10); } $this->assertEqual(5,$count); } } |
以下代码说明了怎样改进(修饰)ADODB_Iterator来满足上述的需求。
require_once ‘adodb/adodb-iterator.inc.php’; |
上述代码中,大多数迭代器接口方法已作为代理来处理结果集了。但是current()方法被重载用于返回fetchObj()方法的结果。
延伸阅读:
从魔兽看PHP设计模式
《PHP设计模式介绍》导言
PHP设计模式介绍 第一章 编程惯用法
PHP设计模式介绍 第二章 值对象模式
PHP设计模式介绍 第三章 工厂模式
PHP设计模式介绍 第四章 单件模式
PHP设计模式介绍 第五章 注册模式
PHP设计模式介绍 第六章 伪对象模式
PHP设计模式介绍 第七章 策略模式
PHP设计模式介绍 第八章 迭代器模式
PHP设计模式介绍 第九章 观测模式
PHP设计模式介绍 第十章 规范模式
PHP设计模式介绍 第十一章 代理模式
PHP设计模式介绍 第十二章 装饰器模式
PHP设计模式介绍 第十三章 适配器模式
PHP设计模式介绍 第十四章 动态记录模式