热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数据源架构模式的活动记录

【活动记录的意图】一个对象,它包装数据表或视图中某一行,封装数据库访问,并在这些数据上增加了领域逻辑。【活动记录的适用场景】适用于不太复杂的领域逻辑,如CRUD操作等。【活动记录的运行机制】对象既有数据又有行为。其使用最直接的方法,将数据访问逻辑置于领域对象中。活动记录的本质是一个领域模型,这个领域模型中的类和基数据库中的记录结构应

【活动记录的意图】

一个对象,它包装数据表或视图中某一行,封装数据库访问,并在这些数据上增加了领域逻辑。

【活动记录的适用场景】

适用于不太复杂的领域逻辑,如CRUD操作等。

【活动记录的运行机制】

对象既有数据又有行为。其使用最直接的方法,将数据访问逻辑置于领域对象中。

活动记录的本质是一个领域模型,这个领域模型中的类和基数据库中的记录结构应该完全匹配,类的每个域对应表的每一列。

一般来说,活动记录包括如下一些方法:

1、由数据行构造一个活动记录实例;

2、为将来对表的插入构造一个新的实例;

3、用静态查找方法来包装常用的SQL查询和返回活动记录;

4、更新数据库并将活动记录中的数据插入数据库;

5、获取或设置域;

6、实现部分业务逻辑。

【活动记录的优点和缺点】

优点:

1、简单,容易创建并且容易理解。

2、在使用事务脚本时,减少代码复制。

3、可以在改变数据库结构时不改变领域逻辑。

4、基于单个活动记录的派生和测试验证会很有效。

缺点:

1、没有隐藏关系数据库的存在。

2、仅当活动记录对象和数据库中表直接对应时,活动记录才会有效。

3、要求对象的设计和数据库的设计紧耦合,这使得项目中的进一步重构很困难

【活动记录与其它模式】

数据源架构模式之行数据入口:活动记录与行数据入口十分类似。二者的主要差别是行数据入口 仅有数据库访问而活动记录既有数据源逻辑又有领域逻辑。

【活动记录的PHP示例】

  1. /**
  2. * 企业应用架构 数据源架构模式之活动记录 2010-10-17 sz
  3. * @author phppan.p#gmail.com http://www.phppan.com
  4. * 哥学社成员(http://www.blog-brother.com/)
  5. * @package architecture
  6. */
  7. /**
  8. * 定单类
  9. */
  10. class Order {
  11.   /**
  12.    * 定单ID
  13.    * @var
  14.    */
  15.   private $_order_id;
  16.   /**
  17.    * 客户ID
  18.    * @var
  19.    */
  20.   private $_customer_id;
  21.   /**
  22.    * 定单金额
  23.    * @var
  24.    */
  25.   private $_amount;
  26.   public function __construct($order_id, $customer_id, $amount) {
  27.     $this->_order_id = $order_id;
  28.     $this->_customer_id = $customer_id;
  29.     $this->_amount = $amount;
  30.   }
  31.   /**
  32.    * 实例的删除操作
  33.    */
  34.   public function delete() {
  35.     $sql = "DELETE FROM Order SET WHERE order_id = " . $this->_order_id . " AND customer_id = " . $this->_customer_id;
  36.     return DB::query($sql);
  37.   }
  38.   /**
  39.    * 实例的更新操作
  40.    */
  41.   public function update() {
  42.   }
  43.   /**
  44.    * 插入操作
  45.    */
  46.   public function insert() {
  47.   }
  48.   public static function load($rs) {
  49.     return new Order($rs['order_id'] ? $rs['order_id'] : NULL, $rs['customer_id'], $rs['amount'] ? $rs['amount'] : 0);
  50.   }
  51. }
  52. class Customer {
  53.   private $_name;
  54.   private $_customer_id;
  55.   public function __construct($customer_id, $name) {
  56.     $this->_customer_id = $customer_id;
  57.     $this->_name = $name;
  58.   }
  59.   /**
  60.    * 用户删除定单操作 此实例方法包含了业务逻辑
  61.    * 通过调用定单实例实现
  62.    * 假设此处是对应的删除操作(实际中可能是一种以某字段来标记的假删除操作)
  63.    */
  64.   public function deleteOrder($order_id) {
  65.     $order = Order::load(array('order_id' => $order_id, 'customer_id' => $this->_customer_id));
  66.     return $order->delete();
  67.   }
  68.   /**
  69.    * 实例的更新操作
  70.    */
  71.   public function update() {
  72.   }
  73.   /**
  74.    * 入口类自身拥有插入操作
  75.    */
  76.   public function insert() {
  77.   }
  78.   public static function load($rs) {
  79.     /* 此处可加上缓存 */
  80.     return new Customer($rs['customer_id'] ? $rs['customer_id'] : NULL, $rs['name']);
  81.   }
  82.   /**
  83.    * 根据客户ID 查找
  84.    * @param integer $id  客户ID
  85.    * @return Customer 客户对象
  86.    */
  87.   public static function find($id) {
  88.     return CustomerFinder::find($id);
  89.   }
  90. }
  91. /**
  92. * 人员查找类
  93. */
  94. class CustomerFinder {
  95.   public static function find($id) {
  96.     $sql = "SELECT * FROM person WHERE customer_id = " . $id;
  97.     $rs = DB::query($sql);
  98.     return Customer::load($rs);
  99.   }
  100. }
  101. class DB {
  102.   /**
  103.    * 这只是一个执行SQL的演示方法
  104.    * @param string $sql  需要执行的SQL
  105.    */
  106.   public static function query($sql) {
  107.     echo "执行SQL: ", $sql, "
    "
    ;
  108.      if (strpos($sql, 'SELECT') !== FALSE) { // 示例,对于select查询返回查询结果
  109.       return array('customer_id' => 1, 'name' => 'Martin');
  110.     }
  111.   }
  112. }
  113. /**
  114. * 客户端调用
  115. */
  116. class Client {
  117.   /**
  118.    * Main program.
  119.    */
  120.   public static function main() {
  121.     header("Content-type:text/html; charset=utf-8");
  122.     /* 加载客户ID为1的客户信息 */
  123.     $customer = Customer::find(1);
  124.     /* 假设用户拥有的定单id为 9527*/
  125.     $customer->deleteOrder(9527);
  126.   }
  127. }
  128. Client::main();
  129. ?>

同前面的文章一样,这仅仅是一个活动记录的示例,关于活动记录模式的应用,可以查看Yii框架中的DB类,在其源码中有一个CActiveRecord抽象类,从这里可以看到活动记录模式的应用

另外,如果从事务脚本中创建活动记录,一般是首先将表包装为入口,接着开始行为迁移,使表深化成为活动记录。

对于活动记录中的域的访问和设置可以如yii框架一样,使用魔术方法__set方法和__get方法。


推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
author-avatar
没有丝袜姑娘
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有