• 技术文章 >后端开发 >php教程

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

    2016-06-01 14:24:23原创336

    【活动记录的意图】

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

    【活动记录的适用场景】

    适用于不太复杂的领域逻辑,如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方法。

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:php使用mb_detect_encoding检测字符串编码 下一篇:iconv和mb_convert_encoding转码函数的区别
    PHP编程就业班

    相关文章推荐

    • PHP中如何读取CSV内容并存入一个数组中• 【php】在Windows2003下的IIS配置php5.4• php基础教程,php基础教程第4版_PHP教程• php模式设计之 注册树模式,php模式设计_PHP教程• php连mysql用 utf-8编码乱码怎么办_PHP教程

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网