老生常谈PHP面向对象之标识映射


Posted in PHP onJune 21, 2017

标识映射在数据映射器的基础上增加了标识映射类,主要功能是保存已经创建好的对象,在需要的时候可以直接获取而不是重复创建造成系统性能的下降。

在数据映射器基础上还增加了部分调用标识映射类的方法,示例代码如下:

namespace woo\domain;

//标识映射类
class ObjectWatcher{
  
  private $all = array();        //存放对象的小仓库
  private static $instance;      //单例
  
  private function __construct (){}
  
  static function instance(){
    if(!self::$instance){
      self::$instance = new ObjectWatcher();
    }
    return self::$instance;
  }
  
  //获取一个唯一的标识,这里采用了领域类类名+ID的方式创建一个唯一标识,避免多个数据库表调用这个类时出现ID重复的问题
  function globalKey(DomainObject $obj){
    $key = get_class($obj) . "." . $obj->getId();
    return $key;
  }
  
  //添加对象
  static function add(DomainObject $obj){
    $inst = self::instance();
    $inst->all[$inst->globalKey($obj)] = $obj;
  }
  
  //获取对象
  static function exists($classname,$id){
    $inst = self::instance();
    $key = "$classname.$id";
    if(isset($inst->all[$key]){
      return $inst->all[$key];
    }
    return null;
  }
}

namespace woo\mapper;

abstract class Mapper{      //抽象基类
  abstract static $PDO;    //操作数据库的pdo对象
  function __construct (){
    if(!isset(self::$PDO){
      $dsn = \woo\base\ApplicationRegistry::getDSN();
      if(is_null($dsn)){
        throw new \woo\base\AppException("no dns");
      }
      self::$PDO = new \PDO($dsn);
      self::$PDO->setAttribute(\PDO::ATTR_ERRMODE,\PDO::ERRMODE_EXCEPTION);
    }
  }
  
  //数据映射器基础上新增的方法以下会简称新增,这里的作用的是获取对象而不是查询数据库并重复创建对象
  //(对比一下原数据映射器的相关代码即可了解)
  private function getFroMap($id){
    return \woo\domain\ObjectWatcher::exists($this->targetClass(),$id);
  }
  
  //新增,这里的作用的是将创建的对象保存起来
  private function addToMap(\woo\domain\DomainObject $obj){//////
    return \woo\domain\ObjectWatcher::add($obj);
  }
  
  
  //对比原数据映射器的代码,便发现它不是直接创建对象而是首先在标识映射类中查找,找不到才调用的
  //子类的方法创建并插入到标识映射类,下面的find方法也遵循了这一原则
  function createObject($array){          
    $old = $this->getFromMap($array['id']);  //新增
    if($old){return $old}          //新增
    $obj = $this->doCreateObject($array);  //在子类中实现
    $this->addToMap($obj);          //新增
    return $obj;
  }
  
  //
  function find($id){                //通过ID从数据库中获取一条数据并创建为对象  
    $old = $this->getFromMap($id);        //新增
    if($old){return $old}            //新增
    
    $this->selectStmt()->execute(array($id));
    $array= $this->selectStmt()->fetch();
    $this->selectStmt()->closeCursor();
    if(!is_array($array)){
      return null;
    }
    if(!isset($array['id'])){
      return null;
    }
    $object = $this->createObject($array);
    $this->addToMap($object);          //新增
    return $object;  
  }
  
  function insert(\woo\domain\DomainObject $obj){      //将对象数据插入数据库
    $this->doInsert($obj);
    $this->addToMap($obj);            //新增
  }
  
  //需要在子类中实现的各抽象方法
  abstract function targetClass();//////
  abstract function update(\woo\domain\DomainObject $objet);
  protected abstract function doCreateObject(array $array);
  protected abstract function selectStmt();
  protected abstract function doInsert(\woo\domain\DomainObject $object);
}

class SpaceMapper extends Mapper {
  //其他代码在数据映射器一文中已有实现这里略过
  //.............
  
  //类名,在标识映射类中生成唯一标识用的
  protected function targetClass(){
    return "woo\\domain\\Space";
  }
}

以上这篇老生常谈PHP面向对象之标识映射就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
Apache设置虚拟WEB
Oct 09 PHP
基于mysql的论坛(2)
Oct 09 PHP
模仿OSO的论坛(五)
Oct 09 PHP
php下通过IP获取地理位置的代码(小偷程序)
Jun 09 PHP
PHP中实现中文字符进制转换原理分析
Dec 06 PHP
php随机生成数字字母组合的方法
Mar 18 PHP
PHP递归遍历指定目录的文件并统计文件数量的方法
Mar 24 PHP
PHP 获取指定地区的天气实例代码
Feb 08 PHP
php str_getcsv把字符串解析为数组的实现方法
Apr 05 PHP
PHP实现的防止跨站和xss攻击代码【来自阿里云】
Jan 29 PHP
php对微信支付回调处理的方法
Aug 23 PHP
PHP实现基本留言板功能原理与步骤详解
Mar 26 PHP
PHP封装的PDO数据库操作类实例
Jun 21 #PHP
PHP基于ORM方式操作MySQL数据库实例
Jun 21 #PHP
php 猴子摘桃的算法
Jun 20 #PHP
详解php框架Yaf路由重写
Jun 20 #PHP
PHP简单计算两个时间差的方法示例
Jun 20 #PHP
php实现的错误处理封装类实例
Jun 20 #PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
Jun 20 #PHP
You might like
PHP基于文件存储实现缓存的方法
2015/07/20 PHP
php文件系统处理方法小结
2016/05/23 PHP
DOM相关内容速查手册
2007/02/07 Javascript
jquery1.4.2 for Visual studio 2010 模板文件
2010/07/14 Javascript
文本框输入时 实现自动提示(像百度、google一样)
2012/04/05 Javascript
JavaScript与DOM组合动态创建表格实例
2012/12/23 Javascript
同域jQuery(跨)iframe操作DOM(示例代码)
2013/12/13 Javascript
简单的jquery左侧导航栏和页面选中效果
2014/08/21 Javascript
用javascript将数据导入Excel示例代码
2014/09/10 Javascript
在AngularJS中使用AJAX的方法
2015/06/17 Javascript
深入浅析JavaScript系列(13):This? Yes,this!
2016/01/05 Javascript
js实现人民币大写金额形式转换
2016/04/27 Javascript
jQuey将序列化对象在前台显示地实现代码(方法总结)
2016/12/13 Javascript
php 修改密码实现代码
2017/05/24 Javascript
详解关于react-redux中的connect用法介绍及原理解析
2017/09/11 Javascript
详解webpack require.ensure与require AMD的区别
2017/12/13 Javascript
JS动画实现回调地狱promise的实例代码详解
2018/11/08 Javascript
微信小程序使用map组件实现检索(定位位置)周边的POI功能示例
2019/01/23 Javascript
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
JavaScript仿京东轮播图效果
2021/02/25 Javascript
使用python删除nginx缓存文件示例(python文件操作)
2014/03/26 Python
使用Python对IP进行转换的一些操作技巧小结
2015/11/09 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
python去除空格和换行符的实现方法(推荐)
2017/01/04 Python
Python的IDEL增加清屏功能实例
2017/06/19 Python
Python编程使用*解包和itertools.product()求笛卡尔积的方法
2017/12/18 Python
在Python中分别打印列表中的每一个元素方法
2018/11/07 Python
使用python Telnet远程登录执行程序的方法
2019/01/26 Python
关于python字符串方法分类详解
2019/08/20 Python
python解析命令行参数的三种方法详解
2019/11/29 Python
python 创建一维的0向量实例
2019/12/02 Python
中专生自荐信
2013/10/12 职场文书
十佳教师事迹材料
2014/01/11 职场文书
珍珠鸟教学反思
2014/02/01 职场文书
幼儿园亲子活动总结
2014/04/26 职场文书
会计工作能力自我评价
2015/03/05 职场文书