老生常谈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&&mysql)四
Oct 09 PHP
php下获取客户端ip地址的函数
Mar 15 PHP
让PHP COOKIE立即生效,不用刷新就可以使用
Mar 09 PHP
php变量范围介绍
Oct 15 PHP
php gzip压缩输出的实现方法
Apr 27 PHP
PHP读取RSS(Feed)简单实例
Jun 12 PHP
PHP清除数组中所有字符串两端空格的方法
Oct 20 PHP
php使用fputcsv()函数csv文件读写数据的方法
Jan 06 PHP
thinkphp命名空间用法实例详解
Dec 30 PHP
Docker搭建自己的PHP开发环境
Feb 24 PHP
PHP函数积累总结
Mar 19 PHP
PHP+百度AI OCR文字识别实现了图片的文字识别功能
May 08 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实现ping
2006/10/09 PHP
做个自己站内搜索引擎
2006/10/09 PHP
字母顺序颠倒而单词顺序不变的php代码
2010/08/08 PHP
CI框架AR操作(数组形式)实现插入多条sql数据的方法
2016/05/18 PHP
Smarty保留变量用法分析
2016/05/23 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
11款基于Javascript的文件管理器
2009/10/25 Javascript
TinyMCE 新增本地图片上传功能
2010/11/05 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
javascript怎么禁用浏览器后退按钮
2014/03/27 Javascript
JavaScript实现继承的4种方法总结
2014/10/16 Javascript
使用Raygun来自动追踪AngularJS中的异常
2015/06/23 Javascript
JS实现淘宝支付宝网站的控制台菜单效果
2015/09/28 Javascript
jquery自定义表格样式
2015/11/23 Javascript
Javascript删除指定元素节点的方法
2016/06/21 Javascript
使用JS和canvas实现gif动图的停止和播放代码
2017/09/01 Javascript
vue-cli的eslint相关用法
2017/09/29 Javascript
vue组件间通信子与父详解(二)
2017/11/07 Javascript
JS浅拷贝和深拷贝原理与实现方法分析
2019/02/28 Javascript
详解微信小程序开发之formId使用(模板消息)
2019/08/27 Javascript
layui使用button按钮 点击出现弹层 弹层中加载表单的实例
2019/09/04 Javascript
使用Node.js在深度学习中做图片预处理的方法
2019/09/18 Javascript
详细分析Node.js 模块系统
2020/06/28 Javascript
JavaScript实现简易计算器小功能
2020/10/22 Javascript
[45:52]完美世界DOTA2联赛PWL S3 Forest vs INK ICE 第二场 12.09
2020/12/12 DOTA
python的类方法和静态方法
2014/12/13 Python
Python实现获取磁盘剩余空间的2种方法
2017/06/07 Python
python实现词法分析器
2019/01/31 Python
selenium WebDriverWait类等待机制的实现
2020/03/18 Python
使用python接受tgam的脑波数据实例
2020/04/09 Python
Mountain Warehouse澳大利亚官网:欧洲家庭户外品牌倡导者
2016/11/20 全球购物
英语专业毕业生自荐信
2013/10/28 职场文书
总监职责范文
2013/11/09 职场文书
文明市民先进事迹
2014/05/15 职场文书
安全生产奖惩制度
2015/08/06 职场文书