老生常谈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 相关文章推荐
动态网站web开发 PHP、ASP还是ASP.NET
Oct 09 PHP
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
Sep 24 PHP
PHP函数学习之PHP函数点评
Jul 05 PHP
CodeIgniter启用缓存和清除缓存的方法
Jun 12 PHP
PHP中soap的用法实例
Oct 24 PHP
php实现两个数组相加的方法
Feb 17 PHP
php用户注册信息验证正则表达式
Nov 12 PHP
PHP函数shuffle()取数组若干个随机元素的方法分析
Apr 02 PHP
php封装的表单验证类完整实例
Oct 19 PHP
原生PHP实现导出csv格式Excel文件的方法示例【附源码下载】
Mar 07 PHP
laravel中数据显示方法(默认值和下拉option默认选中)
Oct 11 PHP
PHP rsa加密解密算法原理解析
Dec 09 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
如何将数据从文本导入到mysql
2006/10/09 PHP
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
ThinkPHP使用smarty模板引擎的方法
2014/07/01 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
JavaScript 异步调用框架 (Part 2 - 用例设计)
2009/08/03 Javascript
jQuery中after的两种用法实例
2013/07/03 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
Javascript中arguments对象详解
2014/10/22 Javascript
js Object2String方便查看js对象内容
2014/11/24 Javascript
javascript中setAttribute()函数使用方法及兼容性
2015/07/19 Javascript
异步JavaScript编程中的Promise使用方法
2015/07/28 Javascript
跟我学习javascript的全局变量
2015/11/16 Javascript
jQuery mobile 移动web(4)
2015/12/20 Javascript
详解Js模板引擎(TrimPath)
2016/11/22 Javascript
详解js静态资源文件请求的处理
2017/08/01 Javascript
vue.js整合mint-ui里的轮播图实例代码
2017/12/27 Javascript
ES6 Symbol数据类型的应用实例分析
2019/06/26 Javascript
[02:41]DOTA2英雄基础教程 亚巴顿
2014/01/02 DOTA
[37:03]完美世界DOTA2联赛PWL S3 INK ICE vs GXR 第二场 12.16
2020/12/18 DOTA
Python 类的特殊成员解析
2018/06/20 Python
Flask框架URL管理操作示例【基于@app.route】
2018/07/23 Python
Python 3.x基于Xml数据的Http请求方法
2018/12/28 Python
学习python的前途 python挣钱
2019/02/27 Python
python3 下载网络图片代码实例
2019/08/27 Python
Python hashlib加密模块常用方法解析
2019/12/18 Python
IE9下html5初试小刀
2010/09/21 HTML / CSS
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
荷兰电脑专场:Paradigit
2018/05/05 全球购物
德国自行车商店:Tretwerk
2019/06/21 全球购物
设计师大码女装:11 Honoré
2020/05/03 全球购物
英文求职信结束语大全
2013/10/26 职场文书
化妆品活动策划方案
2014/05/23 职场文书
禁毒主题班会教案
2015/08/14 职场文书
演讲开头怎么书写?
2019/08/06 职场文书
python调用ffmpeg命令行工具便捷操作视频示例实现过程
2021/11/01 Python
Python获取字典中某个key的value
2022/04/13 Python