老生常谈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 相关文章推荐
利用PHP创建动态图像
Oct 09 PHP
PHP求最大子序列和的算法实现
Jun 24 PHP
微博短链接算法php版本实现代码
Sep 15 PHP
php 生成唯一id的几种解决方法
Mar 08 PHP
php模拟用户自动在qq空间发表文章的方法
Jan 07 PHP
php可扩展的验证类实例(可对邮件、手机号、URL等验证)
Jul 09 PHP
PHP获取当前文件的父目录方法汇总
Jul 21 PHP
Yii2框架中日志的使用方法分析
May 22 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
php fread函数使用方法总结
May 28 PHP
php实现微信公众号创建自定义菜单功能的实例代码
Jun 11 PHP
php输出文字乱码的解决方法
Oct 04 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
php5数字型字符串加解密代码
2008/04/24 PHP
mac系统下安装多个php并自由切换的方法详解
2017/04/21 PHP
简单的邮箱登陆的提示效果类似于yahoo邮箱
2014/02/26 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
JavaScript中获取样式的原生方法小结
2014/10/08 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
JavaScript解析json格式数据简单示例
2014/12/09 Javascript
js和C# 时间日期格式转换的简单实例
2016/05/28 Javascript
同步异步动态引入js文件的几种方法总结
2016/09/23 Javascript
jQuery实现checkbox即点即改批量删除及中间遇到的坑
2017/11/11 jQuery
JS改变页面颜色源码分享
2018/02/24 Javascript
JS通过ajax + 多列布局 + 自动加载实现瀑布流效果
2019/05/30 Javascript
Vue组件之高德地图地址选择功能的实例代码
2019/06/21 Javascript
js+springMVC 提交数组数据到后台的实例
2019/09/21 Javascript
Python3使用PyQt5制作简单的画板/手写板实例
2017/10/19 Python
PyCharm鼠标右键不显示Run unittest的解决方法
2018/11/30 Python
使用Python将Mysql的查询数据导出到文件的方法
2019/02/25 Python
Python何时应该使用Lambda函数
2019/07/02 Python
Python 词典(Dict) 加载与保存示例
2019/12/06 Python
tensorflow安装成功import tensorflow 出现问题
2020/04/16 Python
Django 解决阿里云部署同步数据库报错的问题
2020/05/14 Python
jupyter notebook的安装与使用详解
2020/05/18 Python
深入解析HTML5中的Blob对象的使用
2015/09/08 HTML / CSS
HTML5 直播疯狂点赞动画实现代码 附源码
2020/04/14 HTML / CSS
LVMH旗下最大的奢侈品网站平台:24S
2020/05/24 全球购物
Agoda中文官网:安可达(低价预订全球酒店)
2021/01/18 全球购物
介绍一下HDLC(High-Level Data Link Control)高层数据链路协议
2012/01/21 面试题
Java程序员面试题
2013/07/15 面试题
市场营销专业个人自荐信格式
2013/09/21 职场文书
应届生法律求职信
2013/10/22 职场文书
研发工程师的岗位职责
2013/11/18 职场文书
最新结婚典礼主持词
2014/03/14 职场文书
建筑安全标语
2014/06/07 职场文书
优秀党员先进事迹材料
2014/12/18 职场文书
本科毕业论文答辩稿
2015/06/23 职场文书
基于flask实现五子棋小游戏
2021/05/25 Python