数据源架构模式之行数据入口
【行数据入口的意图】
充当数据源中单条记录入口的对象。每行一个实例
行数据入口提供了看起来像记录结构中记录的对象,但可以用编程语言的常规机制访问它。所有对数据源的访问细节都隐藏在这个接口之后。
【行数据入口的适用场景】
1、适用于事务脚本处理,能够很好的分离数据库访问代码,并且也很容易被不同的事务脚本重用。
【行数据入口的运行机制】
行数据入口是和单条记录极其相似的对象。行数据入口一般能实现从数据源类型到内存中类型的任意转换。
【行数据入口的优点和缺点】
优点:
1、能很好的分享数据库访问代码
2、很容易被不同的事务脚本重用。
3、使用行数据入口,可以在改变数据库结构时不改变领域逻辑。
缺点:
程序写起来比较冗长,代码量相对来说会大一些。
【行数据入口与其它模式】
数据映射器:行数据入口可以和数据映射器一起使用。
数据源架构模式之活动记录:行数据入口可以在移动领域逻辑后演变成活动记录。
【行数据入口的PHP示例】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | <?php /** * 企业应用架构 数据源架构模式之行数据入口 2010-09-27 sz * @author phppan.p#gmail.com http://www.phppan.com * 哥学社成员(http://www.blog-brother.com/) * @package architecture */ class PersonGateway { private $_name; private $_id; private $_birthday; public function __construct($id, $name, $birthday) { $this->setId($id); $this->setName($name); $this->setBirthday($birthday); } public function getName() { return $this->_name; } public function setName($name) { $this->_name = $name; } public function getId() { return $this->_id; } public function setId($id) { $this->_id = $id; } public function getBirthday() { return $this->_birthday; } public function setBirthday($birthday) { $this->_birthday = $birthday; } /** * 入口类自身拥有更新操作 */ public function update() { $data = array('id' => $this->_id, 'name' => $this->_name, 'birthday' => $this->_birthday); $sql = "UPDATE person SET "; foreach ($data as $field => $value) { $sql .= "`" . $field . "` = '" . $value . "',"; } $sql = substr($sql, 0, -1); $sql .= " WHERE id = " . $this->_id; return DB::query($sql); } /** * 入口类自身拥有插入操作 */ public function insert() { $data = array('name' => $this->_name, 'birthday' => $this->_birthday); $sql = "INSERT INTO person "; $sql .= "(`" . implode("`,`", array_keys($data)) . "`)"; $sql .= " VALUES('" . implode("','", array_values($data)) . "')"; return DB::query($sql); } public static function load($rs) { /* 此处可加上缓存 */ return new PersonGateway($rs['id'] ? $rs['id'] : NULL, $rs['name'], $rs['birthday']); } } /** * 人员查找类 */ class PersonFinder { public function find($id) { $sql = "SELECT * FROM person WHERE id = " . $id; $rs = DB::query($sql); return PersonGateway::load($rs); } public function findAll() { $sql = "SELECT * FROM person"; $rs = DB::query($sql); $result = array(); if (is_array($rs)) { foreach ($rs as $row) { $result[] = PersonGateway::load($row); } } return $result; } } class DB { /** * 这只是一个执行SQL的演示方法 * @param string $sql 需要执行的SQL */ public static function query($sql) { echo "执行SQL: ", $sql, " <br />"; if (strpos($sql, 'SELECT') !== FALSE) { // 示例,对于select查询返回查询结果 return array('id' => 1, 'name' => 'Martin', 'birthday' => '2010-09-15'); } } } /** * 客户端调用 */ class Client { /** * Main program. */ public static function main() { header("Content-type:text/html; charset=utf-8"); /* 写入示例 */ $data = array('name' => 'Martin', 'birthday' => '2010-09-15'); $person = PersonGateway::load($data); $person->insert(); /* 更新示例 */ $data = array('id' => 1, 'name' => 'Martin', 'birthday' => '2010-09-15'); $person = PersonGateway::load($data); $person->setName('Phppan'); $person->update(); /* 查询示例 */ $finder = new PersonFinder(); $person = $finder->find(1); echo $person->getName(); } } Client::main(); ?> |
行数据入口本身有更新和插入语句,对于查询的操作放在外部的查询类中,不过也会调用行数据类本身返回数据。
如果有看过Yii框架的源代码,对于以上的示例程序应该有一种很熟悉的感觉!